Общий класс с массивом - PullRequest
1 голос
/ 19 января 2011

Я хочу создать собственный универсальный класс для своего проекта Java, и вот как далеко я продвинулся - я нашел код в качестве примера того, как создавать универсальные массивы.

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

Теперь я получаю ошибку Incompatible types - found: T[], required: T[], которая для меня абсолютно бессмысленна - как я могу это исправить?

Ответы [ 3 ]

4 голосов
/ 19 января 2011

Это имеет смысл, потому что у вас есть два разных параметра типа, называемых T. Однако исправить это довольно сложно, так как я не могу понять, как вы вообще ожидаете, что ваш код скомпилируется.Рассмотрим этот бит:

Array.newInstance(T, size);

T - это имя параметра типа ... его нельзя использовать в качестве аргумента метода.

Обратите внимание, что из-за стирания типаесли вы хотите иметь возможность создавать массив правильного типа, вам нужно указать соответствующий экземпляр Class.Например:

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

... но я не уверен, какой класс Array вы пытаетесь использовать здесь.

1 голос
/ 19 января 2011

Вам нужна переменная, содержащая объект Class для T. Самый простой способ заполнить это, вероятно, статический фабричный метод:

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

Статический метод позволяет вам сказать

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

, который немного короче и менее повторяется, чем

RegisterSet<String> x = new RegisterSet<String>(String.class, 42);
0 голосов
/ 19 января 2011

Есть две ошибки:

Во-первых: класс определяет тип T, а во-вторых, метод определяет его собственный тип T, но оба T не имеют ничего общего друг с другом. - Таким образом, вы должны удалить дополнительный тип T из объявления методов:

public RegisterSet(int size) {

вместо:

 public <T> RegisterSet(int size) {

Второе: метод Array.newInstance требует в качестве первого параметра экземпляр Class, но тип T не является экземпляром класса. - Вам нужно ввести новый параметр типа Class в список аргументов конструктора и использовать этот параметр для создания массива.

По крайней мере, все вместе должно выглядеть так:

  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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...