2013-08-20 3 views
1

В How Generics works in Java разделе this он говоритВнутреннего функционирования Типа Erasure в Дженерики

Java компилятору, когда он видит код, написанный с использованием Generics он полностью стирает этот код и скрытый его в необработанный тип т.е. кода без дженерик. Вся связанная с типом информация - удалена во время стирания. Таким образом, ваш ArrayList становится простым старым ArrayList до JDK 1.5, формальные параметры типа, например. или заменяется либо объектом, либо Суперкласс типа.

Мой вопрос касается последней строки - formal type parameters e.g. <K, V> or <E> gets replaced by either Object or Super Class of the Type.

В каком случае они заменяются Объектом, и в этом случае они заменяются Super Class типа объекта?

Update:

Что происходит, когда у нас есть джокер, как показано ниже?

List<? extends Foo> 
+1

Вы проверяете этот ответ от @RohitJain http://stackoverflow.com/questions/18328546/why-cast-to-generic-type-takes-effect/18328627#18328653 – sanbhat

+0

Он говорит ** Стирание неограниченного type является Object, тогда как стирание параметра ограниченного типа является типом, обозначающим верхнюю границу. ** Я не получаю его, вы можете привести пример. –

+0

The? все еще расширяет Foo. Ответы по-прежнему актуальны. – Bex

ответ

2

Вы уже знаете, что такое стирание. Стирание написано |T|, поэтому |List<String>| is List. Переменные типа, означающие упоминания параметров формального типа, стираются до стирания их левой границы. Наиболее общей формой формального параметра типа T является T extends A1 & A2 & ..., где A1 - An - T s границы.

Для примера

public abstract class Copyable<T extends Copyable<T> & Cloneable> { 
    public T copy() { /* ... */ } 
} 

T в копии будут стерты с стиранием его левая граница. То есть |Copyable<T>| = Copyable.

простых границ могут быть

  • одним прыжка, как в class Enum<E extends Enum<E>>: Самая левая границей является единственной границей, то стирание |Enum<E>| = Enum. не
  • не связаны как в class ArrayList<E>: E действительно имеет неявную грань Object (class ArrayList<E extends Object>), так что стирание |Object| = Object.

Редактировать: В случае List<? extends Foo> вы будете стирать всю вещь; и стирание List<? extends Foo> - |List|.

1

В случае неограниченного типа List<T> стирание будет тип Object.

В случае ограниченного типа List<T extends Foo> стирание будет Foo.

+0

См. Обновленный вопрос. Благодаря! –

+1

@AniketThakur Вы задали вопрос и получили три действительных ответа. Затем вы изменили вопрос и должны были отправлять комментарии к каждому ответу. Урок для изучения здесь - пожалуйста, не редактируйте свой вопрос, чтобы спросить что-то дополнительное. Задайте другой вопрос. –

0

Допустим, у вас есть класс с именем

class Holder<T>{ 
    T obj; 
} 

после типа стирания, он выглядит, как показано ниже, причина Object заменяет неограниченная обобщенный типT

class Holder{ 
    Object obj; 
} 

Допустим, у вас есть класс под названием

class Holder<T extends Cloneable>{ 
    T obj; 
} 

после типа стирания будет

class Holder{ 
    Cloneable obj; 
} 
Смежные вопросы