什么是方法本地类用于?

时间:2013-03-29 09:03:34

标签: java inner-classes

public void foo() {
    class Bar {
    }
    Bar b = new Bar();
}

我看不出任何方法 - 本地类是最佳设计选择的情况。你有没有用过它?在什么情况下?

4 个答案:

答案 0 :(得分:2)

当我需要稍微不同的参数化版本的相同事件监听器附加到不同的swing组件时,我已经使用了一次或两次,但除此之外我倾向于选择匿名类而不是命名本地类。

这个的简单例子是

public void attachListeners(final JLabel label) {
  class ButtonListener implements ActionListener {
    private String value;
    public ButtonListener(String val) { value = val; }
    public void actionPerformed(ActionEvent e) {
      label.setText(value);
    }
  }

  button1.addActionListener(new ButtonListener("value1"));
  button2.addActionListener(new ButtonListener("value2"));
}

答案 1 :(得分:1)

一个用例是,当你对一个interface-type为参数的方法进行循环调用时,该方法只在该方法中使用。因此,您可以定义一个方法本地类,而不是编写一个单独的类。 (匿名类方法可能有效,但如果它在循环中,最好创建一个类。)

interface A{ public int getValue();}
....
public void processValue(A a){}
....
public void showResults(){
    class B implements A{
        int getValue(){
            return value;
        }
    }
    for (int i=0;i<10;i++){
        processValue(new B())
    }
}

答案 2 :(得分:0)

我在需要键值对的情况下使用它,而我的键没有映射到现有类。我不想在我的方法之外提供我的“关键课程”。

作为示例示例,密钥可以由EmployeeDate组成,并且该值是该员工在该日期预订的小时数。在这种情况下,它可能看起来像这样:

public void doExcitingCalculation() {
    class EmployeeDateKey {
        private Employee employee;
        private Date date;
        // Getters and setters ommited for brevity
    }

    Map<EmployeeDateKey, Double> bookedHours = new HashMap<>();
    Map<Empoyee, Map<Date, Double>> temp = fetchData();
    // This isn't a useful datastructure, so we remodel it
    for (Map.Entry<Employee, Map<Date, Double>> entry : temp.entrySet()) {
        for (Map.Entry<Date, Double> hours : entry.getValue().entrySet()) {
            bookedHours.put(new EmployeeDateKey(entry.getKey(), hours.getKey()), hours.getValue());
        }
    }

    // process data
}

答案 3 :(得分:0)

使用方法本地类可以通过将相关部分保持在一起来提高代码的可读性。作为一个人为的例子,假设您有一个方法需要创建一个线程来在后台执行某些操作:

class Test {
 void f() {
    // lots of stuff
    new Thread(new Runnable() {
        public void run() {
            doSomethingBackgroundish();
        }
    }).start();
    // lots more stuff
  }
}

如果没有方法本地类,则必须:

在Test中创建一个新的命名类来进行后台处理,或者 在单独的源文件中创建一个新的命名类来进行后台处理。 这两个选项都可以通过在源树中的其他位置移动相关处理来降低代码的可读性(可能在同一个源文件中,可能完全在另一个源文件中)。使用方法本地类使处理逻辑保持在使用它的位置。

这当然不适用于所有情况,但在许多常见情况下它非常有用。这样的代码通常用于GUI动作侦听器,这是非常小的类,通常只是将动作方法调用从一个地方转发到另一个地方。