Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't assign I <? extends Type> to <Type>?

The following statements:

URLClassLoader ucl = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> uclc = ucl.getClass();

fail with error:

Type mismatch: cannot convert from Class<capture#2-of ? extends URLClassLoader> to Class<URLClassLoader>

Why do I need a cast, here?

I found several posts explaining why You can't do the reverse (assign T to a ), but that's (kind of) obvious and understood.

NOTE: I am coding this under eclipse Luna, so I don't know if it's a Luna Quirk or if there's something I really dont understand in generics.

like image 242
ZioByte Avatar asked Jun 09 '14 08:06

ZioByte


1 Answers

Covariance vs contravariance vs invariance

  • Class<? extends URLClassLoader> is invariant.

As a result,

Class<? extends URLClassLoader> is not a subtype of Class<URLClassLoader>


In Java a variable can hold a reference of an instance of same type or subtype.

Hence,

Class<URLClassLoader> uclc = ucl.getClass();

is invalid.

On the other hand,

Class<? extends URLClassLoader> uclc = ucl.getClass();

would be valid.

like image 129
Tanmay Patil Avatar answered Sep 21 '22 01:09

Tanmay Patil