Перейти к последнему предложению, если вы хотите сразу же прочитать вопрос.Понимание множественного литья в Java
Предположим, что у нас есть интерфейс и три класса:
interface I{}
class A implements I{}
class B extends A {}
И следующие объявления:
A a = new A();
B b = new B();
Теперь, есть классический способ литья, который позволяет мне бросить ссылку типа A (родительский класс) объекту типа B (дочерний класс):
a = b; //here a is no longer pointing at object A, and is now pointing at the same object b is pointing at.
b = (B) a; // the casting is now accepted by the compiler and during runtime as well.
Здесь, где лежит проблема, хотя. Каждый раз, когда я вижу строку кода с несколькими кастами, я не читаю ее (буквально), и, как результат, я не могу понять, что это значит.
Например, скажем, у нас есть эта строка кода:
a = (B)(I)b;
Как бы вы читали это? a
- это ссылка на объект типа A, которому присваивается значение объекта типа B (сначала сбрасывается слева). Но подождите минуту, есть еще один актер (I), предшествующий b. Итак, что мы здесь имеем? Является ли это интерфейсом как объект (B)? или это b, будучи отлитым как интерфейс, который также отливается как (B)?
Я попытался разбить его, чтобы избежать путаницы:
I temp = (I) b;// first line
a = (B) temp;// second line
Итак, сначала, так как б это я (потому что он расширяет, который реализует I), «первая линия» принимается компилятором и во время выполнения.
«Вторая строка», хотя мы имеем ссылку на объект A, которому присваивается значение типа B. На первый взгляд нет ничего плохого в этом. Но потом я понял, что I
не является A и не является B, и даже если приведение в «второй строке» может обмануть компилятор, полагая, что это объект типа B, его нельзя принимать во время выполнения.
Так что главный вопрос, который я хотел бы получить ответ на то, как интерпретировать следующую строку:
a = (B)(I)b;
я бы интерпретировать его как два ненужных слепков. –
Кастинг для интерфейса просто кажется неправильным. – Aziuth
'I' не' B', но 'I' может быть' B' :) – ZhongYu