简体   繁体   English

Java实例化对象,直到运行时才知道它属于哪个子类

[英]java instantiating object without knowing which subclass it will belong to until runtime

Scenario: I have a hierarchy of subclasses all inheriting from a single distance ancestral class. 场景:我有一个子类层次结构,所有这些子类都继承自单个距离祖先类。 All super classes in the hierarchy are abstract, so the only concrete classes are those without subclasses. 层次结构中的所有超类都是抽象的,因此唯一的具体类是那些没有子类的类。 I have an array: 我有一个数组:

AncestralClass[] someObjects1 = new AncestralClass[someLength];

The ancestralClass is the single super class at the top of the hierarchy that all other classes inherit from. ancestralClass是所有其他类都继承自的层次结构顶部的单个超类。 This array is populated with different objects of the various concrete subclasses. 此数组填充有各种具体子类的不同对象。 For example: 例如:

someObjects1[4] = new SubclassObject();

... and so on. ... 等等。

I have a second array of the same exact form (same type, size, etc), but the second array uses the first array to populate itself with objects again belonging to the various concrete subclasses. 我有一个具有完全相同形式的第二个数组(相同的类型,大小等),但是第二个数组使用第一个数组来填充自身,这些对象又属于各个具体的子类。 To be more specific, the object type in an element in the second array, will be decided based on the object type found in the same element of the first array. 更具体地说,第二个数组中元素的对象类型将根据在第一个数组中相同元素中找到的对象类型来确定。 So the problem I have is this: I won't know what is contained in the first array because its contents are generated randomly at runtime, therefore I will not know what the contents of the second array should be as they are dependent on the first array. 所以我的问题是:我不知道第一个数组中包含什么,因为它的内容是在运行时随机生成的,所以我不知道第二个数组中的内容应该是什么,因为它们取决于第一个数组数组。 I am not sure how to write the code that instantiates the new objects in the second array. 我不确定如何编写在第二个数组中实例化新对象的代码。 Written in English, what I want to happen sounds so simple and easy. 用英语写的,我想发生的事情听起来很简单。 I want to loop through the second array, check the corresponding position in the first array, check what kind of object that is, and then instantiate a new object of that type in the second array. 我想遍历第二个数组,检查第一个数组中的相应位置,检查是哪种类型的对象,然后在第二个数组中实例化该类型的新对象。 That right there is what I don't know how to code: 正确的是我不知道如何编码:

someObjects2[i] = new (subclass that someObjects1[i] belongs to)(); 

Question To be more general, I want to instantiate a new object that is a new instance of a class an existing object belongs to. 问题更笼统地说,我想实例化一个新对象,它是现有对象所属类的新实例。 How do I do this, and I'm sure there's multiple solutions, so which is better? 我该怎么做,我确定有多种解决方案,哪个更好?

It seems from your description that you know beforehand the set of possible concrete classes in the first array. 从您的描述看来,您已经预先知道第一个数组中可能的具体类的集合。 You can do something like: 您可以执行以下操作:

for (int i = 0; i < array1.length; i++) {
    if (array1[i] instanceof SubclassObject1) {
        array2[i] = new SubclassObject1();
    } else if (array1[i] instanceof SubclassObject2) {
        array2[i] = new SubclassObject2();
    }
    ....
}

I think this idea is sort of dubious. 我认为这个想法有点可疑。 There's all sorts of problems you can run into trying to create classes of types you don't control in advance. 在尝试创建事先无法控制的类型的类时,您会遇到各种各样的问题。

So if I did this, the first thing I would do is to use a simple factory method, which is the most basic creational pattern. 因此,如果这样做,我要做的第一件事就是使用简单的工厂方法,这是最基本的创建模式。 This way you have all your code isolated in one spot, so if you need to change it later, you can. 这样,您可以将所有代码隔离在一个位置,因此,如果以后需要更改它,则可以。 Then I would just use reflection to create the object. 然后,我只需要使用反射来创建对象。

public class Creation
{
   private Creation() {}

   public static <S, T extends S> S makeNew( T obj )
           throws InstantiationException, IllegalAccessException
   {
      return (S) ( obj.getClass().newInstance() );
   }

   // Demonstration
   public static void main( String[] args )
           throws InstantiationException, IllegalAccessException
   {
      CharSequence[] cs = { new StringBuilder(), new Segment()  };
      for( CharSequence c : cs ) System.out.println( makeNew( c ) );
   }
}

This will work for simple cases. 这将适用于简单的情况。 If you need to use a fancy library like Objenesis in the future, you have an easy place to make your changes. 如果将来需要使用像Objenesis这样的精美库,则可以轻松进行更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM