Two methods when implementing interface containing only one
Asked Answered
I

2

16

I created interface TwoMethods. Source code:

interface TwoMethods<T>
{
    public void method(T t);
}

Then I created class implementing this interface and after disassembling I saw 2 methods. Class:

class A implements TwoMethods<A>
{
    @Override
    public void method(A a) {}
}

After disassembling:

class A implements TwoMethods<A> {
   A();
   public void method(A); //first
   public void method(java.lang.Object); //second
}

Similarly for Comparable interface. Why when I create parametrized interface I have 2 methods. It is always, when I use parameter? I have additionally method with Object as argument?

Inconvenient answered 25/12, 2013 at 10:48 Comment(0)
T
15

If we look at interface TwoMethods bytecode we will see that the actual method is

public abstract method(Ljava/lang/Object;)V

that is at bytecode level information about type parameter does not exist, type is erased, JVM simply does not know about generics, type parameters are replaced either with Object or in case if T extends X with X. So from the point of view of JVM

class A implements TwoMethods<A> {
    public void method(A a) {
        ...

method(A a) does not override interface method because in bytecode it is in method(Object obj) can override it. To fix this problem compiler builds an implicit method, so called bridge method, in class A

public void method(Object obj) {
     method((A)obj);
}

visible in bytecode only. Now for this code

A a = new A();
TwoMethods<A> tm = a;
tm.method(a);

compiler will replace tm.method(a) with call to the bridge

   INVOKEINTERFACE test/TwoMethods.method(Ljava/lang/Object;)V

and this will redirect the call to A.method(A a);

Toddler answered 25/12, 2013 at 11:14 Comment(0)
P
17

method(java.lang.Object) is called the bridge method and it's generated because of type-erasure at compile time.

See Effects of Type Erasure and Bridge Methods

Plebiscite answered 25/12, 2013 at 10:51 Comment(0)
T
15

If we look at interface TwoMethods bytecode we will see that the actual method is

public abstract method(Ljava/lang/Object;)V

that is at bytecode level information about type parameter does not exist, type is erased, JVM simply does not know about generics, type parameters are replaced either with Object or in case if T extends X with X. So from the point of view of JVM

class A implements TwoMethods<A> {
    public void method(A a) {
        ...

method(A a) does not override interface method because in bytecode it is in method(Object obj) can override it. To fix this problem compiler builds an implicit method, so called bridge method, in class A

public void method(Object obj) {
     method((A)obj);
}

visible in bytecode only. Now for this code

A a = new A();
TwoMethods<A> tm = a;
tm.method(a);

compiler will replace tm.method(a) with call to the bridge

   INVOKEINTERFACE test/TwoMethods.method(Ljava/lang/Object;)V

and this will redirect the call to A.method(A a);

Toddler answered 25/12, 2013 at 11:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.