1

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?

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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);

1 Comment

@ApoY2k, because it is a static method, the class's type parameter T is not in scope. The <T> is not part of the return type nor is it the same T as is RegisterSet<T> It is a new type variable and could have been given a different name. What it is saying is "This method can be used as static RegisterSet<String> create(Class<String> clazz, int size) or as static RegisterSet<Integer> create(Class<Integer> clazz, int size) etc.
0

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)

2 Comments

And how would the creation of a new Object look? I tried e.g. new RegisterSet(5, Integer) but that doesn't work (obviously) - but I didn't find any example on how to do it right.
Of course it does not work: because Integer is not an instance of class, but Integer.class is so you need to write: new RegisterSet<Integer>(5, Integer.class)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.