Aamir
Aamir

Reputation: 2422

Generics subtle differences

  class P {

   }
  class Q extends P {

   }
  class R extends Q { 

   }
  class S extends R {

  }

  public class Manager {

    public static void main(String[] args) {

      X<? super R> x4 = null;
      x4.test(new S());
      x4.test(new R());
      x4.test(new P());//compile time error

     }
}

    class X<A> {
      void test(A obj) {

       }
    }

//means that R or superclass of R i.e P, Q or Object but then why I get a compile time error on line as specified in the program.

Upvotes: 2

Views: 132

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280181

Here are some rules from the JLS

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where <: denotes subtyping (§4.10)):

? super T <= ? super S if S <: T

? super T <= ?

? super T <= ? extends Object

T <= ? super T

The notation

X<? super R> x4 = null;

declares X with a generic wildcard type argument that has a lower bound of R.

With the rules above and your declaration of the variable, we can determine that the wildcard covers any sub types of R and R itself. S is a sub type of R, R is R, P is not a sub type of R.

The confusion may come in the following. You can do

X<? super R> x4 = new X<P>();

since P is a superclass of R. However, when you want to use the type parameter of the class X, all you know is that it must at least be an R.

Further reading:

Upvotes: 4

AHH
AHH

Reputation: 1083

You can pass objects extending R, i.e. R or S, but not parents of it. R is the super class of any passed instance!

Upvotes: 0

Related Questions