Такие вещи, как new TreeNode<String>[]
и new TreeNode<E>[]
, запрещены Java. Единственное, что вы можете сделать, это new TreeNode[]
и new TreeNode<?>[]
(неограниченный параметр подстановки).
Причина этого немного сложная, но поучительная. Массивы на Java знают свой тип компонента во время выполнения, и каждый раз, когда вы что-то вставляете, он проверяет, является ли это экземпляром типа компонента, а если нет, генерирует исключение (это связано с тем, что типы массивов ковариантны и поэтому по своей сути небезопасно во время компиляции).
Object[] foo = new Integer[5];
foo[2] = "bar"; // compiles fine, but throws ArrayStoreException at runtime
Теперь добавьте дженерики. Проблема с типом общего типа заключается в том, что нет возможности проверить, является ли объект экземпляром, например, TreeNode<Integer>
во время выполнения (в отличие от TreeNode<String>
), поскольку генерические элементы стираются из типов времени выполнения. Он может проверять только TreeNode
, но не тип компонента. Но программисты, возможно, ожидали, что эта проверка и поведение бросания исключений из массивов, так как это нормально работает. Поэтому, чтобы избежать этого неожиданного сбоя, Java запрещает его. (В большинстве случаев вы все равно не столкнетесь с этой проблемой, потому что вы не будете смешивать объекты одного и того же типа, но с разными параметрами типа. Но теоретически можно подойти.)
Конечно, вы можете просто обойти проблему, создав массив типа сырых или подстановочных параметров, а затем перейдя к соответствующему типу, например (TreeNode<Integer>)new TreeNode[5]
. Какая разница?Ну, это непроверенный актерский состав, который генерирует предупреждение, и вы, программист, берете на себя ответственность за все небезопасные вещи, которые могут произойти позже. Если это что-то неожиданное, компилятор может сказать: «Мы сказали вам!».
Дженерики и массивы _really не играют хорошо вместе. Избегайте использования дженериков с массивами. –