开发者

Generic class with array

开发者 https://www.devze.com 2023-02-06 00:30 出处:网络
I want to create a custom generic class for my Java project and this is how far I got - I found the code as an example on how to create generic arrays.

I want to create a custom generic class for my Java project and this is how far I got - I found the code as an example on how to create generic arrays.

public class RegisterSet<T> {
   private T[] register;开发者_开发百科
   public <T> RegisterSet(int size) {
      register = (T[])Array.newInstance(T, size);
   }
}

Now, I get the error Incompatible types - found: T[], required: T[] which makes absolutely no sense to me - how can I fix this?


It makes perfect sense, because you've got two different type parameters called T. However, fixing it is rather hard as I can't see how you expect your code to compile at all. Consider this bit:

Array.newInstance(T, size);

T is the name of a type parameter... you can't use it as an argument to a method.

Note that due to type erasure, if you want to be able to create an array of the right type, you'll need to specify the relevant Class instance. For example:

public class RegisterSet<T> {
   private T[] register;
   public RegisterSet(Class<T> clazz, int size) {
      register = (T[])Array.newInstance(clazz, size);
   }
}

... but I'm not sure which Array class you're trying to use here.


You need a variable containing a Class object for T. The easiest way to populate this is probably a static factory method:

public class RegisterSet<T> {
   public static <T>RegisterSet<T> create(Class<T> clazz, int size) {
       return new RegisterSet<T>(clazz, size);
   }

   private T[] register;

   @SuppressWarnings("unchecked")
   private RegisterSet(Class<T> clazz, int size) {
      if (clazz.isPrimitive()) throw new IllegalArgumentException("Cannot create a RegisterSet of primitives"); 
      register = (T[])Array.newInstance(clazz, size);
   }
}

The static method allows you to say

RegisterSet<String> x = RegisterSet.create(String.class, 42);

which is slightly shorter and less repetitive than

RegisterSet<String> x = new RegisterSet<String>(String.class, 42);


There are two bugs:

First: The class defines a type T, and second the Method defines it own type T, but both T's hase nothing to do with each other. -- So you have to remove the extra Type T from the methods declaration:

public RegisterSet(int size) {

instead of:

 public <T> RegisterSet(int size) {

Second: The method Array.newInstance requires an instance of Class as its first parameter, but the type T is not an instance of class. - What you need is to intoduce an new parameter of type Class to you constructor argument list, and use this parameter for array creation.

At least all together should look like:

  import java.lang.reflect.Array;

  public class RegisterSet<T> {
    private T[] register;

    public RegisterSet(int size, Class<T> clazz) {
       @SuppressWarnings("unchecked")
       T[] register = (T[]) Array.newInstance(clazz, size);
    }
  }

  ...
  new RegisterSet<Integer>(5, Integer.class)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号