Raw Types
A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:
public class Box < public void set(T t) < /* . */ >// . >
To create a parameterized type of Box , you supply an actual type argument for the formal type parameter T:
Box intBox = new Box<>();
If the actual type argument is omitted, you create a raw type of Box :
Box rawBox = new Box();
Therefore, Box is the raw type of the generic type Box . However, a non-generic class or interface type is not a raw type.
Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:
Box stringBox = new Box<>(); Box rawBox = stringBox; // OK
But if you assign a raw type to a parameterized type, you get a warning:
Box rawBox = new Box(); // rawBox is a raw type of Box Box intBox = rawBox; // warning: unchecked conversion
You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:
Box stringBox = new Box<>(); Box rawBox = stringBox; rawBox.set(8); // warning: unchecked invocation to set(T)
The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.
The Type Erasure section has more information on how the Java compiler uses raw types.
Unchecked Error Messages
As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:
Note: Example.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
This can happen when using an older API that operates on raw types, as shown in the following example:
public class WarningDemo < public static void main(String[] args)< Boxbi; bi = createBox(); > static Box createBox() < return new Box(); >>
The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.
Recompiling the previous example with -Xlint:unchecked reveals the following additional information:
WarningDemo.java:4: warning: [unchecked] unchecked conversion found : Box required: Box bi = createBox(); ^ 1 warning
To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.
Когда нужно использовать raw types?
Сначала вспомним, что такое raw type. В Java так называют generic-типы без указания типа-параметра. Такая языковая конструкция валидна, но в большинстве случаев приводит к предупреждению компилятора.
Предупреждение связано с риском получения проблемы heap pollution. Ей мы уже посвящали публикации ранее. Использование raw types никогда не оправдано – спецификация языка явно говорит: их поддержка остается только для обратной совместимости.
Есть всего три случая, когда использовать обобщенный тип без параметра правильно:
• Целевая версия Java < 5.0 (2002 год и ранее – вряд ли это ваш случай);
• В литерале класса. List.class не сработает, нужно писать List.class ;
• В операторе instanceof . Вместо instanceof Set должно быть instanceof Set .
Java Generics - Raw Types
A raw type is an object of a generic class or interface if its type arguments are not passed during its creation. Following example will showcase above mentioned concept.
Example
Create the following java program using any editor of your choice.
GenericsTester.java
package com.tutorialspoint; public class GenericsTester < public static void main(String[] args) < Boxbox = new Box(); box.set(Integer.valueOf(10)); System.out.printf("Integer Value :%d\n", box.getData()); Box rawBox = new Box(); //No warning rawBox = box; System.out.printf("Integer Value :%d\n", rawBox.getData()); //Warning for unchecked invocation to set(T) rawBox.set(Integer.valueOf(10)); System.out.printf("Integer Value :%d\n", rawBox.getData()); //Warning for unchecked conversion box = rawBox; System.out.printf("Integer Value :%d\n", box.getData()); > > class Box < private T t; public void set(T t) < this.t = t; >public T getData() < return t; >>
This will produce the following result.
Output
Integer Value :10 Integer Value :10 Integer Value :10 Integer Value :10
Kickstart Your Career
Get certified by completing the course
Когда нужно использовать raw types?
Как известно, raw type – это такие generic-типы, которые используются без задания типа-параметра. Данная конструкция допустима, но часто приводит к появлению warning от компилятора. Это связано с риском возникновения ситуации, которая называется heap pollution, это когда переменная, относящаяся к параметризированному типу, начинает ссылаться на непараметризированный объект. Применение raw type, в общем случае, недопустимо. Их поддержка в Java существует исключительно для поддержания совместимости с ранними версиями.
Оправдать применение обобщённого типа без параметров оправдано только в таких случаях:
- Используется Java 5 или более ранняя, выпущенная до 2002 года.
- В литерале class. Когда List.class не выполняется, тогда требуется писать List.class.
Если при использовании instanceof должно быть instanceof Set, а не instanceof Set.
Поделиться уроком
Обучающий бот с бесплатными тестами и практическими заданиями по Kotlin.
Курсовой проект – разработка Телеграм бота на Котлин для изучения иностранных слов. Включает: техническое задание, руководство по поэтапному написанию с код-ревью, работу с сетью и публикацию на сервере. И другие обучающие материалы в закрытом доступе.
