调用匿名类的方法 [英] Invoking a method of an anonymous class
问题描述
我学到了另一天你可以做这个
new Object(){
void hello {
System.out.println(Hello World!);
}
} .hello();
这似乎对我来说很奇怪。当然,创建的对象的静态类型是 Object
,所以没有方法 hello()
?这不是几乎完全没有意义(例如,不能调用 hello
两次)。
有2个问题。
- 有人能指出规范中解决这个问题的部分吗?
- 认为你可以调用
hello
的唯一方法就是这样。 - [...]
- 如果表单是
主要。 [TypeArguments]标识符
,则T
为
主表达式的类型。搜索
的类或接口是T
如果T
是类或接口类型,如果T
是一个类型变量 - Can somebody point me to the part of the specification that addresses this?
- Am I right in thinking that the only way you can invoke
hello
is immediately like this. What about reflection? - [...]
- If the form is
Primary . [TypeArguments] Identifier
, then letT
be the type of the Primary expression. The class or interface to search isT
ifT
is a class or interface type, or the upper bound ofT
ifT
is a type variable.
这将大部分是在有关方法调用表达式的部分中定义:
在编译时处理方法调用的第一步是
找出要调用的方法的名称,哪个类或
接口来搜索该名称的方法的定义。
对于要搜索的类或接口,有六种情况需要考虑,
取决于
左括号之前的形式MethodInvocation:
这里,主表达式是类实例创建表达式。因此,要搜索的类型是匿名类型。
我认为唯一可以调用hello的方法是
立即这样。
只要表达式计算为匿名类型 T
,无论是通过直接访问,或者通过泛型,您都可以访问(常规访问规则适用于) T
声明的成员。这不限于方法。您可以访问字段或类型,但它对类型没有用。例如,
Object var = new Object(){
class Nested {
}
} .new Nested();
由于没有办法引用没有封闭类型的嵌套类型,因此您无法声明该嵌套类型的变量。有用性下降非常快。 (大概,这也是为什么你不能在这个匿名类中有一个 static
嵌套类型。)
也暴露了这种方法。生成的匿名类包含此方法,因此您可以检索它并调用它。过程是一样的。实例来自一个匿名类的事实并不重要。与如果以方法名称作为字符串,我如何调用Java方法?适用。
例如,
Object ref = new Object(){
public void method(){
System.out.println(hidden) ;
}
};
Class<?> anonymousClass = ref.getClass();
方法method = anonymousClass.getMethod(method);
method.invoke(ref,new Object [0]);
不要写这样的代码。 b $ b
I learned the other day that you can do this
new Object() {
void hello() {
System.out.println("Hello World!");
}
}.hello();
This seems really weird to me. Surely the static type of the object created is Object
, so there isn't a method hello()
? Isn't it almost completely pointless (it isn't possible to invoke hello
twice for example).
I have 2 questions about this.
Thanks
Can somebody point me to the part of the specification that addresses this?
This will mostly be defined in the section concerning Method invocation expressions:
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to search for definitions of methods of that name.
For the class or interface to search, there are six cases to consider, depending on the form that precedes the left parenthesis of the MethodInvocation:
Here, the Primary expression is the class instance creation expression. So the type to search is the anonymous type.
Am I right in thinking that the only way you can invoke hello is immediately like this. What about reflection?
As long as an expression evaluates to the anonymous type T
, whether through direct access like you have, or through generics, you have access (regular access rules apply) to the members that T
declares. This isn't limited to methods. You can access fields or types, though it's not as useful for types. For example,
Object var = new Object() {
class Nested {
}
}.new Nested();
Since there's no way to refer to the nested type without the enclosing type, you can't declare a variable of that nested type. The usefulness declines very quickly. (Presumably, that's also why you can't have a static
nested type within this anonymous class.)
Reflection also exposes this method. The generated anonymous class contains this method, so you can retrieve it and invoke it. The process is the same. The fact that the instance is from an anonymous class doesn't matter. The same strategy as presented in How do I invoke a Java method when given the method name as a string? applies.
For example,
Object ref = new Object() {
public void method() {
System.out.println("hidden");
}
};
Class<?> anonymousClass = ref.getClass();
Method method = anonymousClass.getMethod("method");
method.invoke(ref, new Object[0]);
Don't ever write code like this.
这篇关于调用匿名类的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!