JAVA反射将对象强制转换为由特定超类型的名称给定的类

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 = .

例如,我在一个主包中有一个超类动物,在特定的罐子中有一个子类狗和猫。所有类都是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 = ... //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;