1

I found an interesting behavior when using polymorphism in Java lambda expr. I hope someone could shed some light on this.

Assume following things:

public class Java8Test {
    public static void main(String[] args) {
        A a  = new B();
        a.meth((z) -> System.out.println() );
    }
}

interface X
{
    void meth(int a);
}

interface Y
{
    void meth(int a);
}

class A
{
    void meth(X x)
    {
        System.out.println("A");
    }

}

class B extends A
{
    void meth(X x)
    {
        System.out.println("B");
    }
}

If you run Java8Test.main , we get output as

B

We know the "a" refers to B's reference at runtime and so it prints "B" But when we change the method type in Class B as follows

    class B extends A
{
    void meth(Y y)
    {
        System.out.println("B");
    }
}

If you run Java8Test.main , we get output as

A

We know the "a" refers to B's reference at runtime BUT , how come it prints "A" this time ??

tkw83
  • 185
  • 1
  • 5
SaK
  • 103
  • 1
  • 5

4 Answers4

3

The lambda expression is a red-herring. When you change the method signature in class B, it's no longer overriding the

void meth(X x) 

method in class A.

Dave
  • 95
  • 8
  • 1. Dont you think the lamda signature matches on class B meth() as well ? 2. Moreover, it is B's reference is at runtime not A – SaK May 14 '14 at 12:37
  • This just shows that you should always use @Override: http://docs.oracle.com/javase/jp/8/api/java/lang/Override.html – Claude Martin Jun 01 '14 at 18:33
1

In both cases, meth() version of B class is being invoked.

In first case, Overridden meth() is invoked and in second case Inherited meth() is invoked.

As you are extending A class, meth(X x) method will be inherited from parent and meth(X x) and meth(Y y) two distinct methods are present in child B class.

PS : Type of lambda expression is of Target type.

Useful article to understand type of lambda :

  1. Target typing
  2. Java 8 Lambda expressions
Not a bug
  • 4,286
  • 2
  • 40
  • 80
0

This seems to be related to how overloaded methods are resolved with lambda expressions.
Here is a somewhat similar question with a very detailed answer: Java8: ambiguity with lambdas and overloaded methods

Community
  • 1
  • 1
Itay Karo
  • 17,924
  • 4
  • 40
  • 58
0

I think the following happen. When you implement:

void meth(Y y) {
    System.out.println("B");
}

by class B, this method does not override:

void meth(X x) {
    System.out.println("A");
}

of class A. But the variable:

A a  = new B();

is of type A and hence the statement:

a.meth((z) -> System.out.println());

does refere to As method, which consequently will print A.

Harmlezz
  • 7,972
  • 27
  • 35