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

时间:2013-09-06 10:55:43

标签: java

请考虑以下代码:

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类型的对象,而不是我们新的匿名子类的实例。

所以,我的问题是,有没有'好'的方法来实现这种行为?除了明显的(只是,正确地宣布课程)。

4 个答案:

答案 0 :(得分:16)

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

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

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

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

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

答案 1 :(得分:7)

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

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

现在您可以按照以下方式使用它:

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

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

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

答案 2 :(得分:2)

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

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<T> extends T {
  public abstract void doStuff();
}

答案 3 :(得分:0)

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

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