0

Say I have an abstract class called SuperClass and many classes extending it. I have an array of of type SuperClass[]. I want to make an array with new objects of the same subclasses and the same attributes.

I tried to do this by creating instantiating new objects and fill the new array with them. However this doesn't work as demonstrated as follows.

SuperClass[] newArray = new SuperClass[arr.length]; for (int i = 0; i <= arr.length; i++) { SuperClass toBeCopied = arr[i]; newArray[i] = new SuperClass(toBeCopied.attribute1, toBeCopied.attribute2...); 

This does not work because SuperClass is abstract and thus cannot be instantiated.

I also looked at .clone(), but SuperClass doesn't extend Cloneable.

Are there any other ways of making a copy of an array with unknown content types?

7
  • Have you looked at reflection? Commented Apr 29, 2019 at 6:19
  • Have you looked at Arrays.copyOf Commented Apr 29, 2019 at 6:20
  • Sure, you can try to distinguish based on the subtype of each object via instanceof and make copies of concrete objects. Refactoring this inconvenient behaviour would be to extend the super class with a abstract copy or clone method. Commented Apr 29, 2019 at 6:21
  • @Smutje the problem is that there are too many subclasses which would make my code extremely messy and difficult to maintain. Commented Apr 29, 2019 at 6:44
  • Add an public abstract SuperClass copy() method to SuperClass which then needs to be implemented by every subclass Commented Apr 29, 2019 at 7:07

2 Answers 2

1

There's a set of static methods in Arrays that can copy an array. For example: <T> T[] copyOf(T[] original, int newLength). Usage:

abstract class SuperClass { } class SubClass extends SuperClass { } // copy SuperClass[] subClasses = new SubClass[10]; SuperClass[] subClassesCopy = Arrays.copyOf(subClasses, 10); 

-- Update --

Since you want copies of each object within the array, you can define an abstract method in SuperClass and have the subclasses extend it.

 abstract class SuperClass { public abstract SuperClass deepCopy(); } class SubClass extends SuperClass { private String value; public SubClass(String value) { this.value = value; } @Override public SubClass deepCopy() { return new SubClass(this.value); } } 

And then call deepCopy in your code:

 SuperClass[] subClasses = new SubClass[] { new SubClass("1"), new SubClass("2") }; SuperClass[] subClassesCopy = Arrays.stream(subClasses) .map(orig -> orig.deepCopy()) .collect(Collectors.toList()) .toArray(new SuperClass[subClasses.length]); 
Sign up to request clarification or add additional context in comments.

5 Comments

If I do this, wouldn't the contents of the two arrays point to the same objects?
Yes the contents themselves reference the same objects in the original array, this creates a copy of the array, ie, the original and copy array references are different. Do you want to create a copy of each object within the array?
Yes, I want to create a copy of each object within the array.
Updated the answer as per your requirements.
Yes it did. I added an abstract copy method in SuperClass then override in all subclasses. This results in I don't have to know the specific types of the contents to make a copy.
0

You can use reflection to do so

SuperClass[] newArray = new SuperClass[arr.length]; for (int i = 0; i <= arr.length; i++) { SuperClass toBeCopied = arr[i]; newArray[i] = (SuperClass) Class.forName(toBeCopied.getClass().getName()) .getConstructor(String.class, String.class) .newInstance(new Object[] { toBeCopied.getAttribute1(),toBeCopied.getAttribute2() }); } 

Here i am considering, your constructor with two parameters of String type. If you have different type of parameters then change the type at .getConstructor(String.class, String.class).

Sub Type(Class)

public class SubType1 extends SuperClass{ public SubType1(String attribute1, String attribute2) { super(attribute1, attribute2); } } public class SubType2 extends SuperClass{ public SubType2(String attribute1, String attribute2) { super(attribute1, attribute2); } } 

Super Class

public abstract class SuperClass { private String attribute1; private String attribute2; public SuperClass(String attribute1, String attribute2) { // TODO Auto-generated constructor stub this.attribute1 = attribute1; this.attribute2 = attribute2; } public String getAttribute1() { return attribute1; } public void setAttribute1(String attribute1) { this.attribute1 = attribute1; } public String getAttribute2() { return attribute2; } public void setAttribute2(String attribute2) { this.attribute2 = attribute2; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.