Can somebody point me to the part of the specification that addresses this?
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:
[…]
If the form is Primary . [TypeArguments] Identifier, then let T be
the type of the Primary expression. The class or interface to search
is T if T is a class or interface type, or the upper bound of T if T
is a type variable.
Am I right in thinking that the only way you can invoke hello is
immediately like this. What about reflection?
只要表达式计算为匿名类型T,无论是通过直接访问(如您拥有),还是通过泛型,您都具有访问(常规访问规则适用于)T声明的成员。这不限于方法。您可以访问字段或类型,但它对类型没有用。例如,
Object var = new Object() {
class Nested {
}
}.new Nested();
因为没有办法引用没有包围类型的嵌套类型,所以不能声明该嵌套类型的变量。有用性下降非常快。 (大概,这也是为什么你不能在这个匿名类中有一个静态嵌套类型。)
反射也暴露了这种方法。生成的匿名类包含此方法,因此您可以检索它并调用它。过程是一样的。实例来自一个匿名类的事实并不重要。与How do I invoke a Java method when given the method name as a string?中提出的相同的策略适用。
例如,
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]);
不要写这样的代码。