我正在研究我的前同事写的一些Java代码,我发现了一些我无法理解的东西。 这里我们有一个方法getGeneAvailableTaxonomies(),它似乎包含一个带有自己声明的方法调用,accept()。 这是真的吗?可能吗?
这是代码部分:我无法理解从FilenameFilter()到最后的程序的含义。
public List<Integer> getGeneAvailableTaxonomies() {
List<Integer> availableTaxon = new ArrayList<Integer>();
File dataDirectory = new File(_currentApplicationPath, String.format("Data"));
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("gene_") && name.endsWith("_info.info"); //get all info files...
}
};
String[] children = dataDirectory.list(filter);
for(String child:children) {
availableTaxon.add(Integer.parseInt(child.substring(child.indexOf("_")+1, child.lastIndexOf("_"))));
}
return availableTaxon;
}
答案 0 :(得分:8)
您看到定义accept()
方法的代码部分就是所谓的匿名类。
FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.startsWith("gene_") && name.endsWith("_info.info"); //get all info files... } };
这里发生的是创建一个新的类,即FilenameFilter。他们正在实施/覆盖接受方法。可以这样想,但在一个声明中:
class MyFilenameFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return name.startsWith("gene_") && name.endsWith("_info.info");
}
}
FilenameFilter filter = new MyFilenameFilter()
答案 1 :(得分:2)
这是一个匿名内部类,即没有自己名称的类,并且与其实例一起定义了ad-hock。
实际上,根据内部类的顺序编号,此类的名称是外部类的名称,后跟$和数字(1,2,3等)。
答案 2 :(得分:1)
哦,我没有大学。但我从互联网上学到了。
你可以这样做,它不是“方法内部的方法”。它正在实现一个接口。
您可以执行extending an abstract class或实现界面,然后将其直接应用于字段/变量。因为变量/字段可以在方法中使用,所以这是可能的。
<强>被修改强>
您可以在new FilenameFilter() {...
的最后一个大括号后面注意到分号。整个块是一个表达式,因此它可以应用于字段/变量...
答案 3 :(得分:0)
他创建了自己的过滤器来判断dataDirectory
中的文件是否应该包含在String数组中。为此,他必须实现自己唯一的FilenameFilter
接口版本accept
方法。然后他将该过滤器应用于dataDirectory
。
他本可以创建一个可以实现接口的类,但由于它只有一个方法,所以直接在代码中实现它作为匿名类更方便。
答案 4 :(得分:0)
这些被称为匿名类。它们在JLS中有描述,但您可能希望在“Java in a Nutshell”或其他一些教程中阅读它们以便更好地处理它。
答案 5 :(得分:0)
FilenameFilter是一个界面。这里的语法new FilenameFilter(){...}
创建并实例化一个匿名类,该类在内部实现FilenameFilter
。
请参阅File以查看dataDirectory.list()
的内容。 “它返回一个字符串数组,用于命名由此抽象路径名表示的目录中的文件和目录,以满足指定的过滤器。”
答案 6 :(得分:0)
这是发生了什么。语法称为匿名内部类。 new
为您提供了一条提示,即您正在创建一个继承自FilenameFilter
的新类 - 这就是为什么可以将其分配给类型为FilenameFilter
的引用 - 但该类实现了一个名为accept的方法,它会重载FilenameFilter
accept
方法。该类没有名称对程序的其余部分可见(尽管某些编译器至少会在目标目录中创建一个类文件)但只要filter
保留在范围内,它的唯一实例就存在。
这是一种几乎是lambda,它出现在Java中,关于Java 1.2(我认为。)