JAVA反射将对象强制转换为由特定超类型的名称给定的类
例如,我在一个主包中有一个超类动物,在特定的罐子中有一个子类狗和猫。所有类都是JPA实体JAVA反射将对象强制转换为由特定超类型的名称给定的类,java,generics,reflection,Java,Generics,Reflection,例如,我在一个主包中有一个超类动物,在特定的罐子中有一个子类狗和猫。所有类都是JPA实体 public class Animal { } public class Dog extends Animal{ } public class Cat extends Animal{ } 我有一个方法,把动物作为参数 public createAnimal(Animal a){ this.em.persist(a); } 现在我想把Dog或Cat类型的对象传递给该方法 Animal a = .
public class Animal {
}
public class Dog extends Animal{
}
public class Cat extends Animal{
}
我有一个方法,把动物作为参数
public createAnimal(Animal a){
this.em.persist(a);
}
现在我想把Dog或Cat类型的对象传递给该方法
Animal a = ... //read from somewhere...
String myClass = "my.package.Dog";// at runtime
Class specific = Class.forName(myClass);
createAnimal(specific.cast(a));
我不能在我的主程序包中导入狗和猫,因为它必须是通用的(我在其他方面使用它)
那么,我如何才能转换到由名称定义的特定类,并让系统知道这是动物的一个子类型
我需要这样的东西:
Class<Animal> specific = Class.forName(myClass);
Class-specific=Class.forName(myClass);
但是我错过了一些东西。你似乎对演员的表演感到困惑。cast语法,看起来像:
(Dog)someAnimal代码>做3件完全不相关的事情
1) 它所做的第一件事是类型强制,它实际上将一个值从一种类型转换为另一种类型。只有当parens中的东西是原始的,你才能得到这个。例如:intx=(int)5.5代码>将“强制”将5.5(双精度)转换为5(整数)
2) 它做的第二件事是类型检查。当parens中的对象是非基本类型,而不是比表达式更具体的类型时,就会发生这种情况。例如:animala=someAnimal();狗d=(狗)a代码>。你似乎认为这个手术把动物变成了狗。事实并非如此。所有这些都是类型检查:a是Animal
类型的变量,这意味着它要么指向null,要么指向某个对象,该对象是Animal
(类)本身或其任何子类型的实例。“a”属于动物类型,并且指向Cat类型的对象(动物的一个子类型)是完全正确的。写入(Dog)a
将进行类型检查:如果a当前指向类Dog
的某个实例或null,则此操作根本不起任何作用。如果它当前没有指向狗(比如,它指向猫),则该表达式将导致抛出ClassCastException
在任何情况下,此操作都不会转换任何内容
最后一个最为深奥的用法是执行以下操作:dogd=someDog();动物a=(动物)d代码>。在大多数情况下,这是一个完全没有操作,您的IDE会警告您这样做是完全没有意义的;只需动物a=d代码>同样合法。但是,类型仍然会更改,这可能会影响您正在调用的方法以及lambda的类型。如果这对你来说是一件好事,别担心;这基本上是永远不会出现的
您似乎持有的进一步困惑:
对Class
变量的唯一有效赋值是Animal.Class
(和null)<代码>狗。类
不允许出现在那里。如果这是您的意图,那么正确的类型是Class dogClass=Dog.Class;
如果(!Animal.class.isAssignableFrom(dogClass)){/*此处出错*/}
或者还有一个子类:
Class<? extends Animal> animalClass = Dog.class;
Class<? extends Dog> dogClass = animalClass.asSubclass(Dog.class);
assert dogClass == animalClass;
类
Class<?> dogClass = Dog.class;
if (!Animal.class.isAssignableFrom(dogClass)) { /* error here */ }
Class<? extends Animal> animalClass = Dog.class;
Class<? extends Dog> dogClass = animalClass.asSubclass(Dog.class);
assert dogClass == animalClass;