5

I have created anonymous class by implementing interface I inside public static void main() method. So, by java 8 for the abstract method test(), the implementation is provided from imple() method of class C.

So, inside public static void main() method, printing _interface.getClass(), I got

package_path.Main$$Lambda$1/310656974 which is absolutely fine. Bacause it print's the anonymous class name.

Also, _interface is pointing to an anonymous object in heap and hence I'm doing _interface.test();

So, the first statement that test() method has now is to print the class name,

But eventually what it print was, package_path.C (telling me C is the class name). How is that possible? Shouldn't package_path.Main$$Lambda$1/310656974 be printed again? Because 'this' means anonymous inside the test method right?

@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();
    }
}
Naman
  • 27,789
  • 26
  • 218
  • 353

1 Answers1

4

Hopefully, this might help you understand, that when you declare

I _interface = new C()::imple;

you've actually implemented the interface somewhat similar to (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
    }
};

Hence when the test method is called, it first creates an instance of C which prints

class x.y.z.C 

as the class.

Because 'this' means anonymous inside the test method right?

Now as you can see above, there is no more anonymous class from which imple is being called from, hence this is not representing the anonymous class anymore.

As Holger clarified in comments further, despite the representation as lambda or anonymous class at the calling site, the this.getClass() inside a method of class C will evaluate to C.class, regardless of how the caller looks like.

Recommend: Continue to read and follow on Is there any runtime benefit of using lambda expression in Java?

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 1
    Got it, Thanks :) Probably with method reference, I was not able to understand this. With J7 and below implementation of anonymous class, things got clear :) – Manikandan Kbk DIP May 26 '19 at 05:13
  • 1
    @Naman your example implies that a new instance of `C` is created on each call of `test`, this is not correct; it is cached... – Eugene May 26 '19 at 05:49
  • 1
    @Eugene True, I guess it would be more or similar to `C c = new C(); I _interface = () -> c.imple();`. Just that the point I was deriving for OP was the new instance created for the class `C`. – Naman May 26 '19 at 06:03
  • 1
    This answer is misleading. The expression `this.getClass()` inside a method of class `C` will evaluate to `C.class`, regardless of how the caller looks like. But an occurrence of `getClass()` within a lambda expression would not evaluate to an anonymous class either, as lambda expressions and anonymous classes are *not* equivalent. – Holger May 27 '19 at 07:49
  • @Holger *The expression this.getClass() inside a method of class C will evaluate to C.class, regardless of how the caller looks like*... Agreed and that's one point I wanted to illustrate with the expansion for the OP to understand that `this` is not referred from within an anonymous class but class `C` itself. Related to *But an occurrence of `getClass()` within a lambda expression would not evaluate to an anonymous class either* ... I couldn't catch up with you here, did you mean to say that the class representation here is of a Lambda expression and not an Anonymous class? – Naman May 27 '19 at 07:58
  • 2
    Say `Supplier> s = () -> getClass();`. What would `s.get()` give you? It’s *not* an anonymous class implementing `Supplier` or, in other words, `s.get() != s.getClass()`. So rewriting the lambda expressions to an inner class the way you did in your answer will lead to wrong assumptions. – Holger May 27 '19 at 08:08
  • @Holger Thanks for sharing the link. Would update the answer accordingly. Over to you to close as duplicate if you believe the question is already answered as well. – Naman May 27 '19 at 14:37