有没有办法捕获匿名类的类型?
在下面的示例中,我如何调用匿名类的方法g2
?我不会想到一个特别的案例,它绝对有用。并且我知道匿名课程适用于即时课程#34;使用。然而,想知道。
如果我无法调用它,那么在匿名类中使用能够定义它(如果有的话 - 除了作为匿名类本身的其他方法的帮助者)是什么?
// http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
public class SomeClass {
abstract class HelloWorld { abstract public void greet(); }
public void sayHello() {
class EnglishGreeting extends HelloWorld { // local class
String name = "world";
public void greet() { System.out.println("Heya " ); }
public void gg() { System.out.println("do this as well.. ");} }
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() { // anonymous class
public void g2() { System.out.println("do this too.. ");}
public void greet() { System.out.println("Salute "); }
};
englishGreeting.greet();
((EnglishGreeting)englishGreeting).gg();
frenchGreeting.greet();
// ((frenchGreeting.getClass())frenchGreeting).g2(); // gives a checked error
}
public static void main(String... args) {
SomeClass myApp = new SomeClass();
myApp.sayHello();
}
}
注意:看到Can't call anonymous class method& Anonymous Inner Classes Inside Methods以及其他一些相关讨论。
TIA。
// ============================================= =
编辑:
以下工作 - 无论其价值如何都更接近它。在新对象上调用方法时,不查找其引用类型。
HelloWorld frenchGreeting = new HelloWorld() {
public HelloWorld g2() { System.out.println("do this too.. "); return this; }
public void greet() { System.out.println("Salute "); }
}.g2();
答案 0 :(得分:1)
允许您定义非接口方法的原因是因为设计人员在您想要实现帮助方法时考虑了这种情况。
我认为匿名界面被广泛使用。
答案 1 :(得分:1)
你只能直接打电话,例如
new HelloWorld() {
// ...
}.g2();
但是,请注意,您无法分配变量并直接调用它,并且您无法在方法的其他位置调用它。不过,这是我能回答你最接近问题的最接近的事情。
答案 2 :(得分:1)
有没有办法捕获匿名类的类型?
没有。您只能访问它进行反射。
如果我不能调用它,那么在匿名类中能够定义它(如果有的话 - 除了作为匿名类本身的其他方法的帮助者)有什么用呢?
因为它们只能从匿名类型本身引用,所以它们在它之外没用。所以,正如你所说,它们可能被用来组织类中的逻辑,但这就是它。唯一的例外是@ bcsb1001描述的边缘情况,其中您直接在匿名对象创建表达式上调用该方法(而不是为其分配的变量)。
以下工作......
那是因为表达式new HelloWorld() { ... }
的类型是匿名类的类型。由于创建表达式具有实际的匿名类类型,因此您可以使用它来访问它声明的任何成员。但是,由于该类是匿名,因此它没有名称,因此您无法声明具体匿名类型的变量。最接近的是声明变量HelloWorld
。由于变量声明为HelloWorld
,因此您只能使用它来访问在HelloWorld
或其某个超类型上声明的成员。
如果Java在声明中添加了对推断类型的支持,您可以编写类似var g = new HelloWorld() { ... };
(C#样式)或auto g = new HelloWorld() { ... };
(C ++样式)的内容,并推断出g
的类型从任务。这将允许您捕获匿名类型而无需类型名称。但是,Java目前没有这样的功能。