getClass返回什么类型? [英] What type does getClass return?
问题描述
这是我的代码:
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 {
// ...
}
为什么编译器在语句#1
上引发错误?
Why does the compiler raise an error on the statement #1
?
我正在使用Java 7.
I'm using Java 7.
推荐答案
If you take a look at documentation of getClass()
method you will see that
实际结果类型为
Class<? extends |X|>
,其中| X |是擦除在其上调用getClass的表达式的静态类型.例如,此代码段中不需要强制转换:
The actual result type is
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();
因此,e.getClass()
的结果将是Class<? extends Event>
,这正是Set<Class<? extends Event>> s2
应该存储的内容.那就是为什么
So result of e.getClass()
will be Class<? extends Event>
which is precisely what Set<Class<? extends Event>> s2
is suppose to store. That is why
s2.add(e.getClass()); // OK
工作正常.
但是对于Set<Class<Event>> s
,情况几乎没有什么不同.它只能存储Class<Event>
.就类型安全性而言,允许它存储来自Class<? extends Event>
引用的对象将是非常危险的.
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>
reference would be very dangerous in terms of type-security.
看一下这个例子(为了更容易理解,用List
替换Class
,我们的Action
实例将是Animal
,如Dog
和Cat
).
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<>();
现在让我们假设Set<List<Animal>> set
可以存储List<? extends Animal>
Now lets assume that Set<List<Animal>> set
can store 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!
}
还记得我们的List<Dog> dogs = new ArrayList<>();
列表吗?现在它包含Cat
,所以如果我这样做:
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
织物
喵! (psst:让我离开这里!)
...
wof
woof
Woof
Meow! (psst: Get me out of here!)
...
或代替Meow!
的某些异常,例如NoSuchMethodException
或最有可能是ClassCastException: Cat cannot be cast to Dog
.
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.
这篇关于getClass返回什么类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!