Сурови типове в Java

1. Въведение

В този бърз урок ще разгледаме суровите видове, какви са те и защо трябва да ги избягваме.

2. Сурови видове

Необработеният тип е име за родов интерфейс или клас без аргумента за неговия тип:

List list = new ArrayList(); // raw type

Вместо:

List listIntgrs = new ArrayList(); // parameterized type

Списъкът е параметризиран тип интерфейс Списък, докато Списъкът е суров тип интерфейс Списък .

Суровите типове могат да бъдат полезни при взаимодействие с не-родов наследствен код.

В противен случай обаче това е обезкуражено. Това е така, защото:

  1. Те не са изразителни
  2. Липсва им безопасност на типа и
  3. Проблемите се наблюдават по време на изпълнение, а не по време на компилиране

3. Неекспресивно

Суровият тип не документира и се обяснява по начина, по който параметризираният тип.

Лесно можем да заключим, че параметризиран тип Списък е списък, който съдържа String s. При суров тип обаче липсва тази яснота, което затруднява работата с него и с неговите API методи.

Нека видим подписа на метода get (int index) в интерфейса на List, за да разберем по-добре това:

/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException if the index is out of range * (index = size()) */ E get(int index);

Методът get (int index) връща низ в индекс на позиция в параметризиран тип List .

Въпреки това, за суров вид Списък , той връща на обекта . По този начин, от нас се изисква да предприемат допълнителни усилия, за да се запознаят и да се определи вида на елемента в суров вид списъка и добавете подходящ тип леене. Това може да въведе грешки по време на изпълнение, тъй като суровият тип не е безопасен за типа .

4. Не е безопасно за типа

Получаваме предварително генерично поведение със сурови типове. Следователно, суров списък тип приема Object и може да съдържа елемент от всякакъв тип данни . Това може да доведе до проблеми с безопасността на типа, когато смесваме параметризирани и сурови типове.

Нека да видим това, като създадем код, който създава екземпляр на Списък, преди да го предаде на метод, който приема суров тип Списък и добавя цяло число към него:

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); } public void methodB(List rawList) { // raw type! rawList.add(1); }

Кодът получава компилиран (с предупреждение) и число се добавя в суров вид списък , когато бъдат изпълнени. В списъка , който е приет като аргумент сега съдържа String и Integer .

Компилаторът отпечатва предупреждение поради използването на сурови типове:

Note: RawTypeDemo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

5. Проблеми по време на изпълнение

Липсата на безопасност на типа за суров тип има причинен ефект, който може да доведе до изключения по време на изпълнение.

Нека модифицираме предишния пример, така че methodA да получи елемента в позиция индекс 1 от нашия Списък след извикване на methodB :

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); String s = parameterizedList.get(1); } public void methodB(List rawList) { rawList.add(1); }

Кодът се компилира (със същото предупреждение) и хвърля ClassCastException при изпълнение. Това се случва, когато методът get (int index) връща цяло число , което не може да бъде присвоено на променлива от тип String :

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

6. Заключение

Суровите типове са трудни за работа и могат да въведат грешки в нашия код.

Използването им може да доведе до последствия, които могат да бъдат катастрофални и за съжаление, повечето от тези бедствия се случват по време на изпълнение.

Вижте всички фрагменти в този урок в GitHub.