Sometime when looking through code, I see many methods specify an annotation:
@SuppressWarnings(\"unchecked\")
What does this mean?
In Java, generics are implemented by means of type erasure. For instance, the following code.
List hello = List.of("a", "b");
String example = hello.get(0);
Is compiled to the following.
List hello = List.of("a", "b");
String example = (String) hello.get(0);
And List.of is defined as.
static List of(E e1, E e2);
Which after type erasure becomes.
static List of(Object e1, Object e2);
The compiler has no idea what are generic types at runtime, so if you write something like this.
Object list = List.of("a", "b");
List actualList = (List) list;
Java Virtual Machine has no idea what generic types are while running a program, so this compiles and runs, as for Java Virtual Machine, this is a cast to List type (this is the only thing it can verify, so it verifies only that).
But now add this line.
Integer hello = actualList.get(0);
And JVM will throw an unexpected ClassCastException, as Java compiler inserted an implicit cast.
java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer
An unchecked warning tells a programmer that a cast may cause a program to throw an exception somewhere else. Suppressing the warning with @SuppressWarnings("unchecked") tells the compiler that the programmer believes the code to be safe and won't cause unexpected exceptions.
Why would you want to do that? Java type system isn't good enough to represent all possible type usage patterns. Sometimes you may know that a cast is safe, but Java doesn't provide a way to say so - to hide warnings like this, @SupressWarnings("unchecked") can be used, so that a programmer can focus on real warnings. For instance, Optional.empty() returns a singleton to avoid allocation of empty optionals that don't store a value.
private static final Optional> EMPTY = new Optional<>();
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;
return t;
}
This cast is safe, as the value stored in an empty optional cannot be retrieved so there is no risk of unexpected class cast exceptions.