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.