Skip to content

Unchecked Assignment Java Util Arraylist To Array

In this case, it is perfectly okay to suppress the unchecked cast warning.

It's an unchecked cast because is not known at runtime. So the runtime check can only check the cast up to (the erasure of ), but not actually up to itself. (So for example, if were , then if the object's actual runtime class was , it would not be caught by the check even though it's not .)

returns , and not (where would be the type argument of the parameter), because it can be used to create both arrays of primitives and arrays of references. Type variables like cannot represent primitive types, and the only supertype of array-of-primitive types is . objects representing primitive types are parameterized with its wrapper class as the type parameter, e.g. has type . But if you pass to , you will create an , not (which would be ). But if you pass a representing a reference type, will return an .

So basically, calling with a will always return either an , or an array of primitives. An array-of-primitives type is not a subtype of , so it would fail a runtime check for . In other words, if the result is an , it is guaranteed to be an . So even though this cast only checks up to at runtime, and it doesn't check the part from up to , in this case, the check up to is sufficient to guarantee that it is an , and so the unchecked part is not an issue in this case, and it is effectively a fully checked cast.


By the way, from the code you have shown, you do not need to pass a class object to initialize or to use . That would only be necessary if your class actually used the class at runtime. But it doesn't. All it does is create an array (that is not exposed to the outside of the class), and get elements from it. That can be achieved using an . You just need to cast to when you take an element out (which is unchecked by which we know to be safe if we only put s into it):

When the compiler detects potential type-safety issues arising from mixing raw types with generic code, it issues unchecked warnings, including unchecked cast warnings, unchecked method invocation warnings, unchecked generic array creation warnings, and unchecked conversion warnings [Bloch 2008]. It is permissible to use the annotation to suppress unchecked warnings when, and only when, the warning-emitting code is guaranteed to be type safe. A common use case is mixing legacy code with new client code. The perils of ignoring unchecked warnings are discussed extensively in OBJ03-J. Do not mix generic with nongeneric raw types in new code.

According to the Java API, Annotation Type documentation [API 2014],

As a matter of style, programmers should always use this annotation on the most deeply nested element where it is effective. If you want to suppress a warning in a particular method, you should annotate that method rather than its class.

The annotation can be used in the declaration of variables and methods as well as an entire class. It is, however, important to narrow its scope so that only those warnings that occur in the narrower scope are suppressed.

Noncompliant Code Example

In this noncompliant code example, the annotation's scope encompasses the whole class:

This code is dangerous because all unchecked warnings within the class are suppressed. Oversights of this nature can lead to a at runtime.

Compliant Solution

Limit the scope of the annotation to the nearest code that generates a warning. In this case, it may be used in the declaration for the :

Noncompliant Code Example ()

This noncompliant code example is from an old implementation of :

When the class is compiled, it emits an unchecked cast warning:

This warning cannot be suppressed for just the statement because it is not a declaration [JLS 2011]. As a result, the programmer suppresses warnings for the entire method. This can cause issues when functionality that performs type-unsafe operations is added to the method at a later date [Bloch 2008].

Compliant Solution ()

When it is impossible to use the annotation in an appropriate scope, as in the preceding noncompliant code example, declare a new variable to hold the return value and adorn it with the annotation.

Applicability

Failure to reduce the scope of the annotation can lead to runtime exceptions and break type-safety guarantees.

This rule cannot be statically enforced in full generality; however, static analysis could be possible for some special cases.

Bibliography


@SuppressWarnings("unchecked") class Legacy { Set s = new HashSet(); public final void doLogic(int a, char c) { s.add(a); s.add(c); // Type-unsafe operation, ignored } }
class Legacy { @SuppressWarnings("unchecked") Set s = new HashSet(); public final void doLogic(int a,char c) { s.add(a); // Produces unchecked warning s.add(c); // Produces unchecked warning } }
@SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) { // Produces unchecked warning   return (T[]) Arrays.copyOf(elements, size, a.getClass()); }  // ... }
// Unchecked cast warning ArrayList.java:305: warning: [unchecked] unchecked cast found : Object[], required: T[] return (T[]) Arrays.copyOf(elements, size, a.getClass());
// ... @SuppressWarnings("unchecked") T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass()); return result; // ...