Каковы различия между этими кодами с генериками - PullRequest
0 голосов
/ 15 мая 2019

Я заметил, что оба следующих кода работают:

private Node<K,V>[] lst=(Node<K,V>[])(new Node[10]);
private Node<K,V>[] lst=new Node[10];

Есть ли разница между ними? Насколько я понимаю, Node и Node<K,V> относятся к разным типам, и мы не можем создать массив с new Node<K,V>[10], поэтому нам нужно типизировать его с (Node<K,V>[]). Как насчет второго? Почему это работает без приведения типов?

Более того, я заметил, что приведенный выше код не гарантирует правильность типов во время выполнения, как в следующем примере:

List<String> al = new ArrayList<>();
al.add("ax");
al.add("bf");
List<Integer>[] list = (List<Integer>[]) new List[]{al};
System.out.println(list[0]); // ["ax", "bf"] printed

Итак, мой второй вопрос: нужно ли объединять массив и коллекции с генериками? private Node[] lst=new Node[10]; всегда лучший вариант (здесь я не могу использовать List<List<Integer>>, потому что мне нужен массив фиксированного размера). Спасибо!

PS: я знаю некоторые базовые знания о стирании обобщений JVM во время выполнения, я просто не понимаю, как работает приведенный выше код

1 Ответ

0 голосов
/ 16 мая 2019

Есть ли разница между ними?Насколько я понимаю, Node и Node<K,V> относятся к разным типам, и мы не можем создать массив с new Node<K,V>[10], поэтому нам нужно типизировать его с помощью (Node<K,V>[]).

Это на самом делене правда.Node[] и Node<K,V>[] относятся к одному и тому же типу из-за того, как Java обрабатывает их во время компиляции.Кроме того, этот код:

private Node<K,V>[] lst=(Node<K,V>[])(new Node[10]);

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

private Node<K, V>[] lst = new Node<>[10];

Теоретически Java должна выводить дженерики с правой стороны.

Есть ли необходимость объединять массивы и коллекции с дженериками?

Я действительно не понимаю, почему можно было бы даже попытаться объединить коллекции с массивами, но, тем не менее, объединение всех трех делает этот код довольно уродливым.

Закрытый узел [] lst= новый узел [10];всегда лучший вариант?

Зависит от контекста.Когда вы уже знаете, сколько элементов вы хотите сохранить, выберите массив, в противном случае возьмите коллекцию.

Более того, я заметил, что приведенный выше код не гарантирует правильность типов во время выполнения:

List<Integer>[] list = (List<Integer>[]) new List[]{al};

То, что вы в основном пытаетесь здесь сделать, - это создание массива с полиморфными списками.Затем вы создаете новый список (создание экземпляров не LinkedList или ArrayList?) С его первой записью в виде списка строк.Затем вы пытаетесь разыграть его, но способ работы дженериков, как упоминалось ранее, List и List<K> в основном одинаков.Таким образом, во время выполнения вы теряете безопасность типов.Постарайтесь избежать этого.

Я надеюсь, что смогу помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...