Почему возможно создание 3 (/ 4)?
Создание 3 Является ли «алмазный» синтаксис для выводящего типа.Таким образом, new A<>
- это то же самое, что и запись new A<String>
.
. Таким образом, мы можем заменить это длинным синтаксисом до Java 1.7.
A<String> a1 = new A<String>("str");
Это будет проходить через следующий конструкторгде T
было java.lang.String
и t
является java.lang.String
.Обратите внимание, что во время выполнения существует только одна копия этого кода, с необработанным типом T
, равным java.lang.Object
.
public A(T t) {
a = (A<T>) new B();
// ^^^^^^ NB: This will at least give a rawtype warning
// as it causes heap pollution.
a.t = t;
}
Тип a
равен A<T>
во время компиляции и java.lang.Object
стерто.Типы a.t
и t
- T
во время компиляции и java.lang.Object
стерты.Таким образом, он компилируется без предупреждения, и нет приведения для проверки во время выполнения.Назначение выполнено успешно.
Создание 4 использует необработанные типы.Ваш компилятор должен выдать предупреждение (используйте -Xlint
).Игнорирование этих предупреждений может привести к ClassCastException
позже.Обобщения являются «фикцией» компилятора над реальной виртуальной машиной, которая, по существу, следует правилам языка Java 1.0.
Почему объект B способен хранить строку в своей общей целочисленной переменной t?
Стертый тип t
в A
(и, следовательно, B
) равен java.lang.Object
и поэтому может хранить любой ссылочный тип, если проверка отсутствует или неверна.
Почему вызов 5 не выполняется во время выполнения?
Объект a2.a.t
является java.lang.Integer
.a2.a
имеет статический тип A<java.lang.String>
, поэтому статический тип a2.a.t
равен java.lang.String
.javac
вставит приведение, чтобы проверить, что возвращаемый необработанный тип соответствует статическому типу.В этом конкретном случае IIRC, более старые версии javac
неправильно опускают приведение и используют перегрузку println(java.lang.Object)
вместо println(java.lang.String)
.
. Вы можете использовать javap -c -private
, чтобы точно определить, где checkcast
инструкции помещены.
Заключение
Убедитесь, что у вас включены предупреждения.Все, что не имеет их по умолчанию, несколько подозрительно.Не игнорируйте и не подавляйте предупреждения, особенно о необработанных типах.