调用匿名类的方法 [英] Invoking a method of an anonymous class

查看:121
本文介绍了调用匿名类的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学到了另一天你可以做这个

  new Object(){
void hello {
System.out.println(Hello World!);
}
} .hello();

这似乎对我来说很奇怪。当然,创建的对象的静态类型是 Object ,所以没有方法 hello()?这不是几乎完全没有意义(例如,不能调用 hello 两次)。



有2个问题。


  1. 有人能指出规范中解决这个问题的部分吗?

  2. 认为你可以调用 hello 的唯一方法就是这样。

  3. 这将大部分是在有关方法调用表达式的部分中定义:


    在编译时处理方法调用的第一步是
    找出要调用的方法的名称,哪个类或
    接口来搜索该名称的方法的定义。



    对于要搜索的类或接口,有六种情况需要考虑,
    取决于
    左括号之前的形式MethodInvocation:




    • [...]
    • 如果表单是主要。 [TypeArguments]标识符,则 T
      主表达式的类型。搜索
      的类或接口是 T 如果 T 是类或接口类型,如果 T
      是一个类型变量


    这里,主表达式类实例创建表达式。因此,要搜索的类型是匿名类型。


    我认为唯一可以调用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.

    1. Can somebody point me to the part of the specification that addresses this?
    2. Am I right in thinking that the only way you can invoke hello is immediately like this. What about reflection?

    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:

    • [...]
    • 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.

    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆