Вот некоторые необщего код:
public class MyList {
List myData = new ArrayList();
public void add(Object ob) {
myData.add(ob);
}
public Object getAtIndex(int ix) {
return myData.get(ix);
}
}
Этот код позволит вам хранить объект любого типа в ваших MyList случаях даже если договор MyList указывает, что объекты должны быть все одного типа. Более того, если вы используете экземпляр MyList для хранения экземпляров String, вы должны вручную передать их в String при их восстановлении.
String myString = (String) myList.get(1);
Вышеуказанный класс MyList не является безопасным для типа. Вполне возможно, что вышеприведенный оператор присваивания завершится с классом ClassCastException, если объект, отличный от экземпляра String, был сохранен в вашем экземпляре MyList (что может произойти во время выполнения без какой-либо жалобы).
Вот обобщен класс MyList:
public class MyList<T> {
List<T> myData = new ArrayList<>();
public void add(T ob) {
myData.add(ob);
}
public T getAtIndex(int ix) {
return myData.get(ix);
}
}
Теперь компилятор гарантирует, что могут быть добавлены только T
экземпляры и извлекаться из экземпляров MyList. Поскольку компилятор гарантирует, что T
экземпляров всегда будут возвращены, вы можете использовать синтаксис, как это без какого-либо ручного литья:
String myString = myList.get(1);
обобщен класс MyList теперь типобезопасный. Компилятор не позволит вам хранить что-либо, кроме T
экземпляров в экземплярах MyList, что гарантирует отсутствие во время выполнения ClassCastExceptions. Если вы изучите байт-код, вы обнаружите, что компилятор автоматически разместил бросок.
Generics in Java Только компилирование явление. В байтовом коде все ссылки на T
в классе MyList выше заменены на Object
. Этот процесс называется «стирание типа».Важно помнить, что безопасность типов в Java обеспечивается только компилятором. Если ваша программа компилируется без ошибок И без каких-либо предупреждений, то ваша программа, дженерики и все, является безопасным по типу. Однако скомпилированная программа практически не сохранила информацию об общих параметрах.
Это тоталитарная характеристика: компилятор добавляет приведение к байт-коду для вас и гарантирует, что этот прилив не сможет потерпеть неудачу благодаря родовому типу списка. –
http://www.oracle.com/technetwork/articles/java/juneau-generics-2255374.html –
@JBNizet За исключением 'LocalVariableTypeTable' attrbute в байтовом коде, который имеет запись:' 8 30 1 lst Ljava/util/List; 'для общего синтаксиса, оба сценария выглядят одинаково с точки зрения байтового кода, функционально. –
overexchange