Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The compiler issues unchecked warnings when it When the compiler detects potential type-safety issues arising from mixing raw types with generic code. This includes , it issues unchecked warnings, including unchecked cast warnings, unchecked method invocation warnings, unchecked generic array creation warnings, and unchecked conversion warnings [Bloch 082008]. It is permissible to use the @SuppressWarnings("unchecked") annotation to suppress unchecked warnings if when, and only if when, the warning-emitting code is guaranteed to be typesafetype safe. A common usecase use case is mixing legacy code with new client code. The perils of relaxing ignoring unchecked warnings are discussed extensively in MSC10OBJ03-J. Avoid mixing generic and non-generic code if possibleDo not mix generic with nongeneric raw types in new code.

According to the Java API, Annotation Type SuppressWarnings 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 @SuppressWarnings annotation can be used in the declaration of variables , and methods as well as an entire class. It is, however, very important to narrow down its scope so that other noteworthy warnings within the same scope are not silently ignoredonly those warnings that occur in the narrower scope are suppressed.

Noncompliant Code Example

In this noncompliant code example, the @SuppressWarnings annotation's scope encompasses the whole class. This is dangerous as all unchecked warnings within the class will be suppressed. Oversights of this nature can lead to a ClassCastException at runtime.:

Code Block
bgColor#FFCCCC

@SuppressWarnings("unchecked") 
class Legacy {
  Set s = new HashSet();
  public final void doLogic(int a, char c) {
    s.add(a);
    s.add(c); // type Type-unsafe operation, ignored
  }
}

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

Compliant Solution

Limit the scope of the @SuppressWarnings annotation to the nearest unchecked warning generating codecode that generates a warning. In this case, it may be used in the declaration for the Set.:

Code Block
bgColor#ccccff

class Legacy {
  @SuppressWarnings("unchecked")
  Set s = new HashSet();
  public final void doLogic(int a,char c) {
    s.add(a); //produces Produces unchecked warning
    s.add(c); // producesProduces unchecked warning
  }
}

Noncompliant Code Example (ArrayList)

This noncompliant code example is from the an old implementation of java.util.ArrayList. When the class is compiled, it emits an unchecked cast warning, as shown. Since the return statement is not a declaration, the Java Language Specification [JLS 05] makes it impossible to suppress the warning trivially. Therefore, the @SuppressWarnings has been used over method scope. This is can cause issues when some functionality that performs type-unsafe operations is added to the method at a later date. [Bloch 08]:

Code Block
bgColor#FFCCCC

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
  if (a.length < size) {
    // Produces unchecked warning
    return (T[]) Arrays.copyOf(elements, size, a.getClass()); //
 produces unchecked warning}
  // ...
}

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

Code Block

// Unchecked cast warning
ArrayList.java:305: warning: [unchecked] unchecked cast found : 
  Object[], required: T[]
return (T[]) Arrays.copyOf(elements, size, a.getClass());

...

This warning cannot be suppressed for just the return 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 (ArrayList)

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

Code Block
bgColor#ccccff

// ...
@SuppressWarnings("unchecked") 
T[] result =
 (T[]) Arrays.copyOf(elements, size, a.getClass());
return result;
// ...

...

Applicability

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

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SCP04-J

medium

probable

high

P4

L3

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

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

Bibliography

[API 2014]Annotation Type SuppressWarnings
[Bloch 2008]Item 24, "Eliminate Unchecked Warnings"

 

...

Image Added Image Added Image Added[Bloch 08] Item 24: "Eliminate unchecked warnings"