getClass返回什么类型? [英] What type does getClass return?

查看:119
本文介绍了getClass返回什么类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

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,如DogCat).

Take a look at this example (for easier understanding lets replace Class with List and our Action instances will be Animals 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆