Цель
Я создаю класс Java, который предоставит расширенные возможности использования массивов, таких как методы add
, remove
и contains
. Я подумал, что лучшее решение - создать класс (называемый ArrayPP
) с параметром типа T
. Таким образом, пользователь может взаимодействовать с объектом ArrayPP
так же легко, как и с массивом того же типа.
Задача
Я быстро обнаружил, что такие методы, как add
, потребуют создания отдельного массива и в конечном итоге преобразуют целевой массив t
из массива T
s в массив Object
s. Как вы можете догадаться, это полностью разрушает удобство использования, и когда я пытаюсь сделать что-то вроде
File[] f = new File[0];
ArrayPP<File> appF = new ArrayPP(f);
appF.add(saveFile);
f = appF.toArray();
программа выбрасывает
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.io.File;
потому что метод add
должен изменить массив на массив Object
s, так как компилятор Java не позволит вам создать универсальный массив (T[] t = new T[0];
это плохо, но T[] t = (T[]) new Object[0];
нормально) , Из построчной отладки я знаю, что приведенный выше код сохраняет массив t
, в данном случае, как n-массив из File
s, пока не будет вызвана 4-я строка метода add
. У кого-нибудь есть решение, при котором массив t
будет массивом T
с, а не массивом Object
с?
Пример кода
Ниже представлена ОЧЕНЬ разбавленная версия моего класса.
public class ArrayPP<T>
{
T[] t;
/**
* Creates a new Array++ to manage the given array.
* <h3>Analogy:</h3>
* <tt>ArrayPP<String> s = new ArrayPP(args);</tt><br/>
* is analogous to<br/>
* <tt>String s[] = args;</tt>
* @param array The array to be managed
*/
public ArrayPP(T[] array)
{
t = array;
}
/**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP add(T val)
{
T[] temp = (T[]) new Object[t.length + 1];
System.arraycopy(t, 0, temp, 0, t.length);
temp[temp.length - 1] = val;
t = (T[])temp;
return this;
}
/**
* Returns the array at the core of this wrapper
* @return the array at the core of this wrapper
*/
public T[] toArray()
{
return t;
}
}
Возможное решение?
Посмотрев на другие вопросы об универсальных массивах, я думаю, у меня есть решение:
вместо
/**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP add(T val)
{
T[] temp = (T[]) new Object[t.length + 1];
System.arraycopy(t, 0, temp, 0, t.length);
temp[temp.length - 1] = val;
t = (T[])temp;
return this;
}
это будет работать?
/**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP<T> add(T val)
{
t = java.util.Arrays.copyOf(t, t.length + 1);
t[t.length - 1] = val;
return this;
}