Java:如何拥有子类类型的数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17737433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: how to have an array of subclass types?
提问by Mickael Bergeron Néron
Say I have a super class "Animal" and subclasses "Cat", Dog, Bird". Is there a way to have an array of subclass type rather than class instances with which I'll be able to instantiate instances of each possible subclass?
假设我有一个超类“Animal”和子类“Cat”、Dog、Bird“。有没有办法拥有一个子类类型数组而不是类实例,我可以用它来实例化每个可能子类的实例?
To simplify, I want this:
为了简化,我想要这个:
Pseudo code: For each possible subclass of "Animal": create an instance of that class.
How can I do that?
我怎样才能做到这一点?
Edit: I don't want an array of instances of these subclasses, I want an array of object type.
编辑:我不想要这些子类的实例数组,我想要一个对象类型数组。
采纳答案by Freak
After OP's comment
THERE IS NO WAY TO GET ALL SUBTYPES OF A CLASSeven using reflection.
But you can do it by another way , you can say which is the only but longest way.
在 OP 发表评论之后
,即使使用反射也无法获得类的所有子类型。
但是你可以用另一种方式来做,你可以说这是唯一但最长的方式。
- Get a list of names of all classes that exist on the class path
- Load each class and test to see if it is a subclass or implementor of the desired class or interface
- 获取类路径上存在的所有类的名称列表
- 加载每个类并测试它是否是所需类或接口的子类或实现者
Answer before OP's comment
在 OP 评论之前回答
As your question is not clear yet but I guess you want to use array or Collection which will store all of the instances even it is the instance of superclass
or subclass
.Then I guess you need to do like this.
由于您的问题尚不清楚,但我想您想使用 array 或 Collection 来存储所有实例,即使它是superclass
or的实例subclass
。那么我想你需要这样做。
List<Object> list = new ArrayList<Object>();
list.add(new Cat());
list.add(new Dog());
list.add(new Animal());
list.add(new Cat());
for (int i = 0; i < list.size(); i++) {
if(list.get(i) instanceof Cat){
System.out.println("Cat at "+i);
}else if(list.get(i) instanceof Dog){
System.out.println("Dog at "+i);
}else if(list.get(i) instanceof Animal){
System.out.println("Animal at "+i);
}
}
List<Object> list = new ArrayList<Object>();
list.add(new Cat());
list.add(new Dog());
list.add(new Animal());
list.add(new Cat());
for (int i = 0; i < list.size(); i++) {
if(list.get(i) instanceof Cat){
System.out.println("Cat at "+i);
}else if(list.get(i) instanceof Dog){
System.out.println("Dog at "+i);
}else if(list.get(i) instanceof Animal){
System.out.println("Animal at "+i);
}
}
This code is tested
Note:Keep in mind that Don't place parent class check like in case of example code (list.get(i) instanceof Animal)
at top, otherwise it will pass both cases (if checks are only if-if-if) or skip one case(and always return the object as a Animal if checks are if-else if-else if) (list.get(i) instanceof Animal)
and (list.get(i) instanceof Cat)
If the returning object is a Cat object.
此代码经过测试
注意:请记住,不要像示例代码那样(list.get(i) instanceof Animal)
在顶部放置父类检查 ,否则它将通过两种情况(如果检查只是 if-if-if)或跳过一种情况(并且总是如果检查是 if-else if-else if)(list.get(i) instanceof Animal)
并且(list.get(i) instanceof Cat)
如果返回的对象是 Cat 对象,则将对象作为 Animal返回。
回答by Aniket Thakur
You can use Ploymorphism to achieve that.
您可以使用 Ploymorphism 来实现这一点。
Animal[] animalArray = new Animal[10];
animalArray[0] = new Dog();
animalArray[1] = new Cat();
Basically all subclasses of animal Class. When you want to retrieve the objects you can simply typecaset it
基本上是动物类的所有子类。当您想检索对象时,您可以简单地将其排版
Dod dog = (Dog)animalArray[0];
To know the class you can simple use getClass() method. For example
要了解该类,您可以简单地使用 getClass() 方法。例如
Animal[] animalArray = new Animal[10];
animalArray[0] = new Dog();
System.out.println(animalArray[0].getClass());
will print class Dog
.
将打印class Dog
。
回答by Krease
As mentioned in another answer, this is not possible using purely reflection.
正如另一个答案中提到的,这不可能使用纯反射。
Unless you can customize your classes to specifically handle this case, you'd need to dive into either iterating over classes from the class loader, or using a custom class loader that adds the information into an internal data structure so that when it is requested later you don't have to reiterate over all classes.
除非您可以自定义您的类来专门处理这种情况,否则您需要深入研究从类加载器中迭代类,或者使用自定义类加载器将信息添加到内部数据结构中,以便以后请求时您不必在所有课程中重申。
Assuming you're not interested in diving into class loader code (it sounds like you are not), the next best way of doing this is adding static code to your classes that gets run at class loading time. For example:
假设您对深入研究类加载器代码不感兴趣(听起来您没有兴趣),下一个最好的方法是将静态代码添加到在类加载时运行的类中。例如:
public class Animal {
protected static List subclasses = new ArrayList();
//...
}
public class Cat extends Animal {
static {
subclasses.add(Cat.class);
}
//...
}
This would be essentially what you would do with a custom class loader, where this code would live in the class loader instead of the class.
这基本上就是您使用自定义类加载器所做的事情,其中此代码将位于类加载器而不是类中。
Repeat this pattern for all subclasses. Then when you want to create instances, you have class references inside the subclasses
list, which you would instantiate with Class.newInstance
(or another suitable reflection method if your constructors have arguments).
对所有子类重复此模式。然后,当您想要创建实例时,subclasses
列表中有类引用,您可以使用它来实例化Class.newInstance
(或者如果您的构造函数有参数,则使用其他合适的反射方法)。