Raf*_*l T 4 java generics casting weak-linking
今天我遇到一个让我真的很奇怪的功能.因此,我们假设这个简单的结构用于清除.
public class Animal{
public String getName(){ return null; }
}
public class Dog extends Animal{
@Override
public String getName(){
//I'm aware that not any Dog's name is 'Pluto', but its just a Sample ;)
return "Pluto"
}
}
public class Cat extends Animal{
protected final String mName;
public Cat(String name){
mName = name;
}
@Override
public String getName(){
//cats have different names, because the internet loves cats
return mName;
}
public void miao(){
//just a dummy
}
}
Run Code Online (Sandbox Code Playgroud)
现在将a指定Dog给Animal指针是绝对有效的,但是将指定Animal给Dog指针的指针无效:
Animal animal = new Dog(); //valid, any Dog is at least an Animal
Dog dog = new Animal(); // invalid, of course not any Animal is a Dog!
Run Code Online (Sandbox Code Playgroud)
让我们假设一个AnimalCage类,其中发生了"魔术":
public class AnimalCage{
private ArrayList<Animal> mCage = new ArrayList<Animal>();
public addAnimal(Animal animal){
mCage.add(animal);
}
// HERE is where the "Magic" happens:
public <A extends Animal> A getAnimalByName(String name){
//try catch block not mandatory
try{
for (Animal a: mCage){
if (name.equals(a.getName()) return (A)a;
}
} catch(ClassCastException cce){}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
使用AnimalCage它可以做到这一点:
//all valid
AnimalCage cage = new AnimalCage();
Dog dog = new Dog();
Cat cat = new Cat("Mauzi");
Cat cat2 = new Cat("Garfield");
cage.add(dog);
cage.add(cat);
cage.add(cat2);
// and later get it back
//will return dog
Dog pluto = cage.getAnimalByName("Pluto");
//will find nothing and return null
Dog snoopy = cage.getAnimalByName("Snoopy);
//will raise ClassCastException and return null
snoopy = cage.getAnimalByName("Mauzi");
//will return Mauzi
Animal mauzi = cage.getAnimalByName("Mauzi");
Run Code Online (Sandbox Code Playgroud)
所以我可以做任何事情而不用明确表达.这引出了我的假设Erasures,虽然我知道的更好,但这些假设在运行时没有被删除.之前我认为我必须至少给出一个关于如何投射这个函数的指标:
public <A extends Animal> A getAnimalByName(String name, Class<A> animalClass){
try{
for (Animal a: mCage){
if (name.equals(a.getName()) return (A)a; }
} catch(ClassCastException cce){}
return null;
}
//use
Dog dog = cage.getAnimalByName("Pluto", Dog.class);
Run Code Online (Sandbox Code Playgroud)
我真的很想知道Java如何让我在Cats/Dogs上分配动物,以及它对动物的专长是什么
我不太明白你的问题,但也许我可以澄清一些观点:
Singnature例如<A extends Animal> A getAnimalByName(String name)涉及一种称为类型推断的技术- 即从赋值的左侧推断出A特定调用的实际类型getAnimalByName().
请注意,它是纯粹的编译时功能 - 代码如
<A extends Animal> A getAnimalByName(String name) { ... }
...
Dog dog = getAnimalByName("foo");
Run Code Online (Sandbox Code Playgroud)
编译时会变成以下代码(由于类型擦除):
Animal getAnimalByName(String name) { ... }
...
Dog dog = (Dog) getAnimalByName("foo");
Run Code Online (Sandbox Code Playgroud)正如您所看到的,您的代码会破坏类型安全保证 - 当您执行强制转换时会发生这种情况return (A) a,编译器会发出警告.它是泛型的基本保证 - 如果您的代码在没有警告的情况下编译,它不会破坏类型安全性.
| 归档时间: |
|
| 查看次数: |
536 次 |
| 最近记录: |