Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow. Alter...
#5: Post edited
- I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);- ```
Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varargs `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Note that the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
- I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator =
- new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, casting to `Class<?>` and then casting it again to `Class<SomeSubClass<String>>` is ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- If you think it's too confusing, you could create a helper method to do the cast:
- ```java
- public class ClassUtils {
- public static <T> Class<T> cast(Class<?> c) {
- return (Class<T>) c;
- }
- }
- ```
- And then use it like this:
- ```java
- ExampleClass<SomeSubClass<String>> creator =
- new ExampleClass<>(ClassUtils.<SomeSubClass<String>>cast(SomeSubClass.class));
- ```
- Not sure which one is uglier, but anyway.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varargs `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Note that the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
#4: Post edited
- I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
- I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varargs `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Note that the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
#3: Post edited
I'm afraid there's no easy, straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
- I'm afraid there's no straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
#2: Post edited
- I'm afraid there's no easy, straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
- I'm afraid there's no easy, straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
- # Alternative 1: `Class` object informed in the constructor
- You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
- ```java
- import java.lang.reflect.Array;
- public class ExampleClass<S extends SomeClass> {
- private Class<S> arrayClass;
- public ExampleClass(Class<S> arrayClass) {
- this.arrayClass = arrayClass;
- }
- public S[] createArray(int n) {
- return (S[]) Array.newInstance(arrayClass, n);
- }
- }
- ```
- With a `Class` instance we can use [`java.lang.reflect.Array`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/reflect/Array.html) to create an array of the desired type and length.
- I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
- ```java
- ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
- SomeSubClass[] array = creator.createArray(10);
- ```
- Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
- ---
- ### But what if `SomeSubClass` is also generic?
- Let's say `SomeSubClass` also has a generic type:
- ```java
- // parent class, not generic
- class SomeClass {
- }
- // subclass, generic
- class SomeSubClass<T> extends SomeClass {
- }
- ```
- And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
- ```java
- ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
- ```
- Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
- ---
- # Alternative 2: varargs
- Another way to solve it is to change the method to receive a varargs argument of the desired type:
- ```java
- import java.util.Arrays;
- public class ExampleClass<S extends SomeClass> {
- public S[] createArray(int length, S... elements) {
- return Arrays.copyOf(elements, length);
- }
- }
- ```
- This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.
- With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
- ```java
- // No need to provide a Class object
- // It works even if SomeSubClass is a generic type
- ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
- SomeSubClass<String>[] array = ec.createArray(5);
- ```
- Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
- As a bonus, you can also initialize some of (or all) the elements of the array:
- ```java
- // first and seconds elements will be set to instance1 and instance2, respectively
- // the other elements will be null
- SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
- ```
#1: Initial revision
I'm afraid there's no easy, straighforward way to do that. Due to type erasure, we don't have enough information to create the array directly. Therefore, this information must be provided somehow.
# Alternative 1: `Class` object informed in the constructor
You could force all instances of `ExampleClass` to be created with a `Class<S>` object:
```java
import java.lang.reflect.Array;
public class ExampleClass<S extends SomeClass> {
private Class<S> arrayClass;
public ExampleClass(Class<S> arrayClass) {
this.arrayClass = arrayClass;
}
public S[] createArray(int n) {
return (S[]) Array.newInstance(arrayClass, n);
}
}
```
I admit it might be annoying to provide a `Class` object for every new instance of `ExampleClass`. But now it works:
```java
ExampleClass<SomeSubClass> creator = new ExampleClass<>(SomeSubClass.class);
SomeSubClass[] array = creator.createArray(10);
```
Assuming, of course, that `SomeSubClass` is a subclass of `SomeClass`.
---
### But what if `SomeSubClass` is also generic?
Let's say `SomeSubClass` also has a generic type:
```java
// parent class, not generic
class SomeClass {
}
// subclass, generic
class SomeSubClass<T> extends SomeClass {
}
```
And I want to create an array of `SomeSubClass<String>`. Unfortunately, passing just `SomeSubClass.class` doesn't compile. Trying something like `SomeSubClass<String>.class` doesn't compile either. And a cast such as `(Class<SomeSubClass<String>>) SomeSubClass.class` also doesn't compile. So you need to do this trick:
```java
ExampleClass<SomeSubClass<String>> creator = new ExampleClass<>((Class<SomeSubClass<String>>) (Class<?>) SomeSubClass.class);
```
Yes, it's ugly, but it works: now `createArray` will return an array of `SomeSubClass<String>`.
---
# Alternative 2: varargs
Another way to solve it is to change the method to receive a varargs argument of the desired type:
```java
import java.util.Arrays;
public class ExampleClass<S extends SomeClass> {
public S[] createArray(int length, S... elements) {
return Arrays.copyOf(elements, length);
}
}
```
This solution provides information about the type in the varags `elements`, so that `Arrays.copyOf` can create an array of the correct type.
With this, you don't need to provide a `Class` object anymore, which makes it less cumbersome, specially if the type is also generic (no need to do the ugly cast trick):
```java
// No need to provide a Class object
// It works even if SomeSubClass is a generic type
ExampleClass<SomeSubClass<String>> ec = new ExampleClass<>();
SomeSubClass<String>[] array = ec.createArray(5);
```
Due to vargs, the `elements` argument is optional, so passing just the size will set all elements to `null`, just like it happens when you create a new array with `new Type[size]`.
As a bonus, you can also initialize some of (or all) the elements of the array:
```java
// first and seconds elements will be set to instance1 and instance2, respectively
// the other elements will be null
SomeSubClass<String>[] array = ec.createArray(5, instance1, instance2);
```
