使用任意定义的匿名接口方法

请考虑以下代码:

public static void main(String[] args) { File file = new File("C:\\someFile.txt") { public void doStuff() { // Do some stuff } }; file.doStuff(); // "Cannot resolve method" } 

当我们尝试调用我们新定义的方法doStuff() ,它是不可能的。 原因是file被声明为File类型的对象,而不是我们新的匿名子类的实例。

所以,我的问题是,有没有“好的”方法来实现这种行为? 除了显而易见的(只是,正确地宣布类)。

这是不可能的,因为你试图在超类引用上调用方法子类。 并且该方法没有在超类本身中定义。 匿名类只是File的子类。

但是,解决方法是进行反思:

 file.getClass().getMethod("doStuff").invoke(file); 

getClass()方法将返回file的运行时类型,然后您可以使用Class#getMethod()方法获取该类的方法。

好吧,我自己并不是反思的忠实粉丝。 如果你要做这些事情,更好的方法当然是通过扩展超类来创建一个类。 这将是一个痛苦的头脑,使用reflection工作出路,通过简单的修改可以轻松完成。

好的方法是不要在你的情况下使用匿名内部类,而是定义你自己的类,扩展File并添加你需要的任何方法。

 class StuffedFile extends File { // implement all needed constructors public void doStuff() { /*.....*/} } 

现在您可以使用它如下:

 MyFile f = new MyFile("..."); f.doStuff(); 

然而,整个扩展File尝试并不是一个好的设计。 创建其他可以接受文件并在其上执行操作的类。 您将获得更好的封装和代码可重用性。

编辑显然你可以使用reflection调用你想要的任何方法,但我不能称之为“好的解决方案”。 我可以称之为“可能的解决方法”。

最近我能够达到你的简洁程度是:

 public static void main(String[] args) { abstract class FileThatDoesStuff extends File { // Need a constructor that takes a String because File has one. public FileThatDoesStuff(String filePath) { super(filePath); } // It also does stuff. public abstract void doStuff(); } FileThatDoesStuff file = new FileThatDoesStuff("C:\\someFile.txt") { @Override public void doStuff() { // Do some stuff } }; file.doStuff(); // "Can resolve method" } 

我不得不承认我希望我能做到:

 abstract class DoesStuff extends T { public abstract void doStuff(); } 

可以访问该方法。 但我不知道你为什么要这样做。

 public static void main(String[] args) { new File("C:\\someFile.txt") { public void doStuff() { // Do some stuff } }.doStuff(); }