Создайте многомерный универсальный массив опций - PullRequest
0 голосов
/ 11 января 2019

Я хочу создать двумерный массив (да, я знаю, что это на самом деле массив массивов), содержащий Optionals. Обычный подход для создания универсального массива не работает, так как он терпит неудачу с ClassCastException. Вот мой код:

@SuppressWarnings("unchecked")
Optional<Integer>[][] arr = (Optional<Integer>[][]) new Object[5][5];

Есть ли способ создать такой массив, если да, каков будет подход к этому?

Ответы [ 3 ]

0 голосов
/ 11 января 2019

В Java « запрещено создавать массив универсального типа, параметризованного типа или параметра типа». «Почему нельзя создавать универсальный массив? Потому что он не безопасен от типов. Если бы он был законным, приведение, сгенерированное компилятором в другой правильной программе, могло бы завершиться ошибкой во время выполнения с ClassCastException. Это нарушило бы фундаментальную гарантию, предоставляемую универсальная система типов." [Джошуа Блох - Эффективная Java]

Итак, какие решения позволяют создавать многомерные массивы?

Рекомендуется использовать контейнер:

List<List<Optional<Integer>>> arr = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    arr.add(new ArrayList<Optional<Integer>>());
}
0 голосов
/ 13 января 2019

В общем, вы не можете разыграть Object[][] в Optional[][]. Вы получите ClassCastException во время выполнения. Массив должен быть создан как Optional[][], а не как Object[][]. Но дженерики обычно являются предпочтительными необработанными типами.

Дело не в том, что вы никогда не сможете создавать массивы генериков. Вы должны сделать это косвенно. Как правило, способ сделать это состоит в том, чтобы создать массивы обобщенных шаблонов с неограниченным подстановочным знаком, а затем выполнить непроверенное приведение - как вы сделали - к нужному типу:

@SuppressWarnings("unchecked")
Optional<Integer>[][] arr = (Optional<Integer>[][]) new Optional<?>[5][5];

Вышеприведенное относится к созданию любых массивов некоторого определенного универсального типа. В этом случае вы можете рассмотреть возможность использования OptionalInt вместо Optional<Integer>. Это позволяет обойти любые опасения относительно массивов генериков.

(В целом, я несколько подозрительно отношусь к идее создания массивов или коллекций Optionals любого вкуса. Это просто кажется странным занятием. Альтернативы часто бывают лучше. Но в некоторых случаях это может быть оправдано. В любом случае. вопрос о том, подходит ли массив Optionals для какой-либо проблемы, которую вы пытаетесь решить, - это отдельный вопрос.)

0 голосов
/ 11 января 2019

Недопустимо создавать массив обобщений в Java из-за безопасности типов. Попробуйте вместо этого использовать списки. Ссылка на руководство Oracle: https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays

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