简体   繁体   中英

What type does getClass return?

Here is my code:

Set<Class<Event>> s = new HashSet<>();             
Set<Class<? extends Event>> s2 = new HashSet<>();
Event e = new Event();                         

s.add(e.getClass());   // #1
s2.add(e.getClass());  // #2

class Event {
    // ...
}

Why does the compiler raise an error on the statement #1 ?

I'm using Java 7.

If you take a look at documentation of getClass() method you will see that

The actual result type is Class<? extends |X|> Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:

 Number n = 0; Class<? extends Number> c = n.getClass(); 

So result of e.getClass() will be Class<? extends Event> Class<? extends Event> which is precisely what Set<Class<? extends Event>> s2 Set<Class<? extends Event>> s2 is suppose to store. That is why

s2.add(e.getClass());   // OK 

works fine.


But in case of Set<Class<Event>> s things are little different. It can store only Class<Event> . Allowing it to store objects from Class<? extends Event> Class<? extends Event> reference would be very dangerous in terms of type-security.

Take a look at this example (for easier understanding lets replace Class with List and our Action instances will be Animal s like Dog and Cat ).

List<Dog> dogs = new ArrayList<>(); 
List<? extends Animal> generalList = dogs;

Set<List<Animal>> set = new HashSet<>();

Now lets assume that Set<List<Animal>> set can store List<? extends Animal> List<? extends Animal>

set.add(generalList);

Now we are able to do something horrible as

for (List<Animal> animalList : set){
    animalList.add(new Cat()); // I just placed Cat in container full of Dogs!
}

Remember our List<Dog> dogs = new ArrayList<>(); list? Now it contains Cat so if I do:

for (Dog dog : dogs){
    dog.speak();
}

I will probably see something similar to

wof
woof
Woof
Meow! (psst: Get me out of here!)
...

or instead of Meow! some exception like NoSuchMethodException or most probably ClassCastException: Cat cannot be cast to Dog .

So as you see allowing this mechanism wouldn't be very wise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM