Чому java generics не може бути в масивах?


10

Чому так відбувається, коли я намагаюся зробити масив ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];є помилка, і java цього не дозволяє?

Чи є причина, пов’язана з реалізацією дженерики, генерики будь-якою мовою Java, чи щось довільне?


Відповіді:


20

Це одна з головних дірок у дженері Java, масиви є коваріантними , тобто масив типів Foo[]є підкласом Object[]та ParentOfFoo[]. Порівнюйте це з тим, у List<Foo>кого немає такої поведінки.

Це було важливо, коли у Java не було дженериків (до Java 5), ​​оскільки в іншому випадку щось на зразок загальної функції сортування було просто неможливим.

Однак є ця складна проблема, що масиви люблять знати, який тип вони виконують під час виконання . Однак дженерики на Java базуються на стиранні типу. Ці дві речі взагалі не добре поєднуються, і саме тут ми маємо свою проблему.

Тож довгий і короткий його - у Java 1, коваріантні масиви частково заповнювали дірку, яку створив дефіцит генерики. Однак, коли вони намагалися належним чином заповнити цю діру, зворотна сумісність означала, що масиви було неможливо реалізувати.

Насправді хлопець, який насправді створив основу для дженериків, Мартін Одерський, розповів про це тут під час інтерв'ю про те, чому він створив Scala. (Досить захоплююче, якщо вас взагалі цікавить історія Скали)


3

Чи є причина, пов’язана з реалізацією дженерики, генерики будь-якою мовою Java, чи щось довільне?

Насправді це дещо довільно.

Проблема полягає в тому, що вона дозволяє дірити в системі типів, оскільки ArrayList<T>[]її можна передати Object[]і потім ви можете помістити ArrayList<U>в масив, куди U != T.

Дизайнери Java вирішили перекрити цю діру якомога охоче, не дозволяючи new ArrayList<T>[N]взагалі.

Однак це може бути також підключено, не допускаючи оновлення масивів генеричних даних (без попередження "не перевірено").


Ця відповідь занижена. Дуже просто і не використовує жаргон на невиразних умовах. Дуже дякую.
Tung Nguyen

Можливо, ви захочете IntegerObject[]String[]
Калет

-3

тому що масив є коваріантним, кожен тип - це підклас об'єкта, тому це дає помилку в часі виконання через виключення кастингу. в той час як загальне є інваріантним, тому коли він базується на типі secure або type-safe, тому якщо тип не такий, як він створює тип, він створює помилку компілятора.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.