Reputation: 3
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?
Upvotes: 0
Views: 409
Reputation: 613
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;
}
}
Upvotes: 0
Reputation: 1154
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]);
Upvotes: 1