【问题标题】:Why does this.getClass give it's own class name rather than Anonymous class name?为什么 this.getClass 给它自己的类名而不是匿名类名?
【发布时间】:2019-05-26 04:56:57
【问题描述】:

我通过在 public static void main() 方法中实现接口 I 创建了匿名类。所以,java 8 对抽象方法 test() 的实现是由 C 类的 imple() 方法提供的。

所以,在 public static void main() 方法中,打印 _interface.getClass(),我得到了

package_path.Main$$Lambda$1/310656974 这绝对没问题。因为它打印的是匿名类名。

另外,_interface 指向堆中的一个匿名对象,因此我正在做 _interface.test();

所以,test() 方法现在的第一条语句是打印类名,

但最终打印出来的是, package_path.C (告诉我 C 是类名)。这怎么可能?不应该再次打印 package_path.Main$$Lambda$1/310656974 吗?因为“this”在测试方法中意味着匿名,对吧?

@java.lang.FunctionalInterface
interface I {
    void test();
}

class C {
    void imple() {
        System.out.println(this.getClass());
        System.out.println("Inside Implementation");
    }
}

class Main {
    public static void main(String[] args) {
        I _interface = new C()::imple;
        System.out.println(_interface.getClass());
        _interface.test();
    }
}

【问题讨论】:

    标签: java java-8 anonymous-class functional-interface


    【解决方案1】:

    希望这可以帮助您理解,当您声明时

    I _interface = new C()::imple;
    

    您实际上实现的接口有点类似于 (though not same as):

    I _interface = new I() {
        @Override
        public void test() {
            new C().imple(); // creating an instance of class `C` and calling its 'imple' method
        }
    };
    

    因此当test 方法被调用时,它首先创建一个C 的实例并打印

    class x.y.z.C 
    

    作为班级。

    因为“this”在测试方法中是匿名的,对吧?

    现在正如你在上面看到的,没有更多的匿名类来自imple 被调用,因此this 不再代表匿名类。

    正如 Holger 在 cmets 中进一步澄清的那样,尽管在调用站点上表示为 lambda 或匿名类,但在类 C 的方法中的 this.getClass() 将评估为 C.class,无论调用者看起来如何。

    推荐:继续阅读并关注Is there any runtime benefit of using lambda expression in Java?

    【讨论】:

    • 知道了,谢谢 :) 可能有方法参考,我无法理解这一点。使用 J7 及以下匿名类的实现,事情就变得清晰了:)
    • @Naman 您的示例暗示在每次调用test 时都会创建一个C 的新实例,这是不正确的;它被缓存了...
    • @Eugene 是的,我想它会更多或类似于C c = new C(); I _interface = () -> c.imple();。只是我为 OP 得出的​​观点是为 C 类创建的新实例。
    • 这个答案具有误导性。 this.getClass()C 的方法中的表达式 this.getClass() 将评估为 C.class,无论调用者看起来如何。但是在 lambda 表达式中出现 getClass() 也不会计算为匿名类,因为 lambda 表达式和匿名类等效。
    • Supplier<Class<?>> s = () -> getClass();s.get() 会给你什么?它不是实现Supplier 或换句话说s.get() != s.getClass() 的匿名类。因此,按照您在答案中所做的方式将 lambda 表达式重写为内部类会导致错误的假设。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    相关资源
    最近更新 更多