请考虑以下代码:
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
类型的对象,而不是我们新的匿名子类的实例。
所以,我的问题是,有没有'好'的方法来实现这种行为?除了明显的(只是,正确地宣布课程)。
答案 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();
}