Question

I have some questions about bridge method creating. We can apply bridge technique for covariant overriding. Now consider example from the official help:

public class Node<T>{
    private T data;
    public Node(T data){ this.data=data;}
    public void setData(T data){
         System.out.println("Node.setData");
         this.data=data;
    }
}
public class MyNode extends Node<Integer>{
    public MyNode(Integer data){ super(data); }
    public void setData(Integer data){
         System.out.println("MyNode.setData");
         this.data=data;
    }
}

Let bridge method doesnt creating. Hence at run time class MyNode have two methods: setData(Integer) and setData(Object) where last is inheritated from Node. When we are calling setData(new Inetegr(5)) will called setData(Integer). If we write Object o= new Integer(5); setData(o); then setData(Object) will called. It is not true. So two questions:

  1. Am i understand the reason for introduction bridge method correctly?
  2. What is the necesseraly and enough conditions for bridge method creating?
Was it helpful?

Solution

Am i understand the reason for introduction bridge method correctly?

I think yes. If compiler didn't generate the bridge method, then the method in the subclass would be an overloaded version of super class method, and not the overridden version. As you already seem to understand.

What is the necesseraly and enough conditions for bridge method creating?

When you extend or implement a parameterized type, and type erasure changes the signature of the method in the super class.

If we write Object o= new Integer(5); setData(o); then setData(Object) will called. It is not true.

I don't understand what do you mean by that. You should test this behaviour on non-generic code. When a method is overloaded, then a method call is binded to which method is decided at compile-time, based on the declared type of the parameter you pass. Since the declared type in this case is Object, it will invoke setData(Object) version.

OTHER TIPS

This is a compiler which applies bridge technique, not us. In your case the compiler will insert the bridge here:

class MyNode extends Node<Integer> {
  public void setData(Object data) {
     setData((Integer) data);
  }
...

And this is why it is used:

    Node<Integer> n = new MyNode();
    n.setData(1);

Node does not have setData(Integer) it has setData(Object). MyNode bridge method setData(Object) overrides it. JVM detects that actual type of n is MyNode and calls MyNode.setData(Object) which will redirect to setData(Integer).

Another case when bridge methods are applied is covariant return type:

class X implements Cloneable {
    @Override
    public X clone() {
         ...
    }

bridge is needed to actually override Object.clone. Note that in bytecode method signature includes return type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top