Вопрос по java, generics, arrays – Ошибка компиляции универсального создания массива из внутреннего класса

5

Я пытаюсь реализовать связанную коллекцию с использованием обобщений, что-то вроде следующего.

public class A<E> {

  private class B {

    private B[] b;
    private E item;

    private B() {
      this.b = new B[2];
    }

  } // end inner class B

} // end class A

A - это коллекция, а B - элемент или узел в коллекции с массивом, ссылающимся на преемников / предшественников и элемент.

Создание массива не допускается. Я получаю ошибкуgeneric array creation, Правильно ли я считаю, что то, что он на самом деле создает, представляет собой массивA<E>.B?

Если нет, что является причиной ошибки?

Если так, как я могу обойти это?

Я, очевидно, опустил значительное количество кода, если того, что я предоставил, недостаточно, дайте мне знать. Любой совет будет принят во внимание. Спасибо.

EDIT 1: Я должен был упомянуть, что параметризованный тип должен быть одинаковым вA как вB, Так мимоходом<E> для внутреннего класса не представляется возможным, так как это создаетE#2 и уходитA сE#1.

Вы также можете обойти это, используя универсальную коллекцию вместо массива. trutheality
WRT Edit1, попробуйтеstatic class B<E> и у вас не возникнет проблема с именами. Массив все равно не будет работать, так как это Generic. Anony-Mousse
Еслиb на самом деле всегда есть два элемента, вам, вероятно, лучше использовать два поля. Tom Hawtin - tackline
Не совсем ответ на ваш вопрос, но было бы лучше иметь две переменные «предшественник»; и «преемник»; типа B, а не массив из двух элементов. Сделал бы ваш класс легче для чтения. Я полагаю, это также заставит вашу проблему уйти? Rajesh J Advani

Ваш Ответ

3   ответа
4

B наследует универсальный от внешнего класса, так как он не является статическим. И вы не можете просто сделать это статичным, потому что тогда потребуетсяE также.

Так что вашиB.b массиву действительно нужен тип, который является универсальным, т.е.A<E>.B или если вы измените свой код наstatic внутренний класс,A.B<E> (если бы вы использовалиprivate static class B<E>).

В Java из-за способа реализации обобщенных типов (путем стирания) тип массива не является четко определенным. С одной стороны, это должен быть массивBс другой стороны, это должен быть массивObject.

Наиболее работоспособным решением является использованиеObject[] и бросить явно. Если вы хотите повысить безопасность типов, вы можете, конечно, использоватьArrayList<B>, который внутренне используетObject[], тоже!

В вашем конкретном коде,B b1, b2; также может быть опцией, которая на самом деле быстрее (без проверки границ) и требует меньше памяти (без объекта массива; без информации о размере).

Я думал об использовании отдельных ссылок b1, b2. Кажется, это самый подходящий путь. Это просто делает более сложным обход коллекции в некоторых методах. Спасибо за ваш отзыв, очень полезно. comfortablejohn
2

B это нестатический внутренний класс. Это означает, что у него есть ссылка на экземпляр окружающего класса. Таким образом, он неявно параметризован параметром типа внешнего класса. Поэтому, когда вы пишетеB, это значитA<E>.B, Чтобы создать массив, вы должны использовать необработанный класс. Тем не мение,B не необработанный класс; чтобы ссылаться на необработанный класс, вам нужно явно указать его:A.B

Итак, это то, что вы хотите:

this.b = new A.B[2];
-2

 private class B<E> {

            private B[] b;
            private E item;

            private B() {
                this.b = new B[2];
            }

        } // end inner class B
Извините, я не вижу никакой выгоды. В твоих настройках это ИМХО должно бытьprivate static class B<E> не получить перегрузку имени, и это все еще не позволитnew B[2] создание массива.
Разве это не дает ту же ошибку?
Да. И согласно моему редактированию, я требую, чтобы типы были одинаковыми как во внешнем, так и во внутреннем классе. Выполнение вышеизложенного будет означать, что хотя они оба могут быть превращены в один и тот же тип, скажем,A<Integer> делает их обоими целыми числами, они не сопоставимы и не совместимы при ссылках между ними. comfortablejohn

Похожие вопросы