Upcasting не вызывает стирание типа? - PullRequest
0 голосов
/ 06 мая 2019

Недавно я столкнулся с кодом, понижающим object до String после проверки instanceof.

Object obj = this.get(key);
if(obj instanceof String) {
    return (String) object;
}

Я немного запутался, как это работает. Насколько я понимаю, он не работает с шаблонами, потому что Type Erasure оставляет экземпляр без ссылки на исходный класс. Кроме того, мое понимание (подтвержденное этим ответом ) заключается в том, что во время выполнения нет никакой разницы между повышением до Object и использованием универсального типа T. Означает ли это, что единственная причина, по которой instanceof недействителен для обобщений, связана с перечисленными здесь проверками времени компиляции здесь ?

Тип операнда RelationalExpression оператора instanceof должен быть ссылочным типом или нулевым типом; в противном случае возникает ошибка времени компиляции.

Это ошибка времени компиляции, если ReferenceType, упомянутый после оператора instanceof, не обозначает ссылочный тип, который можно переопределять (§4.7).

Если приведение выражения RelationalExpression к ReferenceType будет отклонено как ошибка времени компиляции, то выражение реляционного экземпляра аналогичным образом выдает ошибку времени компиляции. В такой ситуации результат выражения instanceof никогда не может быть истинным.

Несмотря на это, ответы, подобные тем, которые даны в на этот вопрос , по-видимому, означают, что есть различия в поведении во время выполнения. Это то, что объекты обычно do содержат информацию о типе во время выполнения, но это стирается в случае обобщений? Как эта информация типа не будет удалена в случае апскейтинга?

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

1 Ответ

2 голосов
/ 06 мая 2019

Объекты всегда знают, какого они типа.

Стирание типов означает, что универсальные типы «теряются» в скомпилированном коде. Например. List<String> компилируется в необработанный List, логически эквивалентный List<Object>

Однако присвоение String переменной, объявленной как Object, не приводит к стиранию типа, поскольку:

  1. Это не универсальный тип, поэтому удаление типа не применимо.

  2. Объект знает, что это String, независимо от объявленного типа переменной .
    Вот почему вы можете спросить это:

    • Вы строка? x instanceof String

    • Кто ты? x.getClass()

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