public void foo() {
class Bar {
}
Bar b = new Bar();
}
我看不出方法本地类是最佳设计选择的任何情况。你用过吗?在什么情况下?
public void foo() {
class Bar {
}
Bar b = new Bar();
}
我看不出方法本地类是最佳设计选择的任何情况。你用过吗?在什么情况下?
当我需要附加到不同摆动组件的同一事件侦听器的参数化版本略有不同时,我使用过一次或两次,但除此之外,我倾向于使用匿名类而不是命名本地类。
一个简化的例子是
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"));
}
一个用例是,当您对具有接口类型作为参数的方法进行循环调用时,并且该方法仅在该方法中使用。因此,您可以定义一个方法本地类,而不是编写一个单独的类。(匿名类方法可能有效,但如果它在循环中,最好创建一个类。)
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())
}
}
我在需要键值对并且我的键没有映射到现有类的情况下使用它。我不想让我的“关键类”在我的方法之外可用。
例如,键可以由 aEmployee
和 a组成Date
,值是该员工在该日期的预订小时数。在这种情况下,它可能如下所示:
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
}
使用方法本地类可以通过将相关部分放在一起来增加代码的可读性。作为一个人为的示例,假设您有一个方法需要创建一个线程来在后台执行某些操作:
class Test {
void f() {
// lots of stuff
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
// lots more stuff
}
}
如果没有方法本地类,您将不得不:
在 Test 中创建一个新的命名类来做后台处理,或者在一个单独的源文件中创建一个新的命名类来做后台处理。这两个选项都可以通过将相关处理移动到源树中的其他位置来降低代码的可读性(可能在同一个源文件中,也可能完全在另一个源文件中)。使用方法本地类可以将处理逻辑保持在使用它的位置。
这当然不是适用于所有情况,但它在许多常见情况下非常有用。此类代码通常用于 GUI 操作侦听器,它们是非常小的类,通常只是将操作方法调用从一个地方中继到另一个地方。