Тип безопасности: непроверенный актерский состав и Generics - PullRequest
3 голосов
/ 10 марта 2011

У меня есть очень простая карта

private Map<String,T> map = Collections.synchronizedSortedMap(new TreeMap<String,T>());

Я хотел бы определить следующий метод

public T[] values(){
    return (T[])map.values().toArray();
}

И, очевидно, я сталкиваюсь с неконтролируемой проблемой приведения ..Моя проблема в том, что я не могу вызвать toArray(new T[size]).

Что мне нужно сделать, чтобы избежать этого предупреждения (без использования @SuppressedWarning)

Спасибо

Ответы [ 4 ]

4 голосов
/ 10 марта 2011

Избегайте массивов.Return List<T>.

Массивы являются необходимыми базовыми строительными блоками, однако они довольно странные в системе типов.Лучше избегать их в API.Почти везде массив может быть заменен ArrayList.Производительность такая же.

0 голосов
/ 10 марта 2011

Чтобы получить массив универсального типа, вы должны передать объект Class в ваш метод, в противном случае он вернет массив типа Object [].

public T[] values(Class<T> cl){
    return (T[])map.values().toArray((T[])Array.newInstance(cl,0));
}

Вам все еще нужно использовать SuppressdWarning для этого кода, но он не будет выбрасываться во время выполнения. Также, если вам это нужно для реализации collection.values ​​(), вы должны передать класс в ваш ctor. Массивы и Generics просто плохо сочетаются, поэтому вы должны использовать коллекции.

0 голосов
/ 10 марта 2011

Что я должен сделать, чтобы избежать этого предупреждения (без использования @SuppressedWarning)

Это предупреждение - последнее, о чем вам следует беспокоиться. Большая проблема заключается в том, что, когда это возвращается кому-то, кто ожидает массив с определенным классом, происходит сбой с ClassCastException.

Поскольку массивы в Java содержат ссылку на их класс компонентов во время выполнения, невозможно создать такой массив, не зная этого класса. Либо пользователь передаст что-то с, что позволит вам получить объект класса для класса T, либо вам просто нужно будет вернуть Object[]

0 голосов
/ 10 марта 2011

Лучшее, что я могу придумать, - это создать конструктор для вашего класса, который принимает массив типа T (т.е. аргумент T []). Ожидается, что пользователь вашего класса предоставит массив нулевого размера. Затем вы можете использовать этот массив для вызова toArray (T []).

...