0

Am having Class A ,Interfaces B,C . aA extends A,aB implements B,cC implements C.But if I try to use MultipleBounded Generics.It is showing compilation error using jdk 1.7. Please help me to correct the errornous. LINK FOR REFERENCE

public class MultipleBounds {
    public static void main(String args[]) 
    {
      D d1 = new D();
      d1.print(new bB()); // compilation Error
      d1.print(new cC()); // compilation Error
      d1.print(new aA()); // It works no Issues
    }
}

class A {
    public void method() {
        System.out.println("methodA");
    }
}

interface B {
    public void method();
}

interface C {
    public void method();
}

class aA extends A {
    public void method() {
        System.out.println("methodaA");
    }
}

class bB implements B {
    public void method() {
        System.out.println("methodbB");
    }
}

class cC implements C {
    public void method() {
        System.out.println("methodcC");
    }
}

class D<T extends A & B & C> 
{
    public void print(T t)
    {
        t.method();
    }
}
sunleo
  • 10,589
  • 35
  • 116
  • 196

2 Answers2

3

Since you are using raw type D for invoking the method, all the generic information from the class is lost. And the method print will be replaced by it's erasure.

Now, the erasure of the type parameter T is the left-most bound it has, which is A. This is evident in JLS §4.6:

The erasure of a type variable (§4.4) is the erasure of its leftmost bound.

So, what compiler sees is this:

class D {
    public void print(A t)
    {
        t.method();
    }  
}

That is why, it works for A and not for B and C. Lesson: Avoid using raw types.

Community
  • 1
  • 1
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
2

The problem is here: D d1 = new D();. You are using a raw type, therefore losing the generics information. And the type erasure of a type intersection A & B & C is its first component (A). So your d1 can only accepts As.

For example, if you reorder it to B & A & C, you will only be able to pass Bs.

Finally note that you would not be able to declare your D using generics because no class in your code is an A and a B and a C. You could create a class ABC extends A implements B, C and use D<ABC> d = new D<>();

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • But there is no difference of or or .Becasue then what is the use of the multiple bounded. – sunleo Jan 18 '14 at 12:13
  • @sunleo You'll see the difference, once you use parameterized type. You can't create a `D`, but you can create a `D`. – Rohit Jain Jan 18 '14 at 12:13
  • @sunleo `T extends A & B` means that you expect a type that is an A _and_ a B. But you need to declare your `D` class with generics to see it. See my last paragraph. – assylias Jan 18 '14 at 12:14