What Is Suppresswarnings ("Unchecked") in Java

What is SuppressWarnings (unchecked) in Java?

Sometimes Java generics just doesn't let you do what you want to, and you need to effectively tell the compiler that what you're doing really will be legal at execution time.

I usually find this a pain when I'm mocking a generic interface, but there are other examples too. It's usually worth trying to work out a way of avoiding the warning rather than suppressing it (the Java Generics FAQ helps here) but sometimes even if it is possible, it bends the code out of shape so much that suppressing the warning is neater. Always add an explanatory comment in that case!

The same generics FAQ has several sections on this topic, starting with "What is an "unchecked" warning?" - it's well worth a read.

Does the placement of @SuppressWarnings(unchecked) matter?

You must not place annotations like @SuppressWarnings("unchecked") on a statement but only on a declaration.

That's why the compiler does not understand the first variant:

@SuppressWarnings("unchecked")
v.addElement(new Integer(1_000_000));

It's just illegal there and the compiler won't understand it.

You could put it on the method instead, if you want to reduce the scope:

@SuppressWarnings("unchecked")
public static void main(String [] args) {
Vector v = new Vector();
v.addElement(new Integer(1_000_000));

Thus, only warnings for the main method will be ignored, but not for the whole class.

You can even put it on the variable declaration, but never on a statement:

@SuppressWarnings("unchecked")
Vector v = new Vector();

However, as GhostCat has pointed out, in this case it is probably better to just generify the vector instead of ignoring warnings.

SuppressWarnings annotation when assigning to instance variable

You expected to suppress warning when there's an issue, the issue is inside doSomething in line

this.map = Library.getMap();

You can't suppress the assignment itself, so you need to go to the outer scope which is the method or the class

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.

If you assignment would be in initialization, you could suppress it:

@SuppressWarnings("unchecked" )
private Map<String, String> map = Library.getMap();

Performance considerations when using @SuppressWarnings(unchecked)

As far as I know, @SuppressWarnings annotations have no performance implications. They don't materially alter the bytecodes that are generated.

Unnecessary type casts in the source code should be omitted by the byte code compiler, but the compiler will include whatever type-casts are necessary to ensure runtime type safety, irrespective of the suppression of warnings1.

Furthermore if (hypothetically) the compiler does insert some type-cast bytecodes that are not strictly necessary, they should be optimized away by the JIT compiler.


However, it is better to write your code so that you don't need to use @SuppressWarnings annotations. The problem is that the annotations can hide logic errors in your code; i.e the warnings can be real. If not detected by thorough unit and integration testing, these can lead to unexpected runtime errors.


1 - If the compiler didn't do this, then the bytecodes would fail verification when loaded by the JVM.

What is the list of valid @SuppressWarnings warning names in Java?

It depends on your IDE or compiler.

Here is a list for Eclipse Galileo:

  • all to suppress all warnings
  • boxing to suppress warnings relative to boxing/unboxing operations
  • cast to suppress warnings relative to cast operations
  • dep-ann to suppress warnings relative to deprecated annotation
  • deprecation to suppress warnings relative to deprecation
  • fallthrough to suppress warnings relative to missing breaks in switch
    statements
  • finally to suppress warnings relative to finally block that don’t
    return
  • hiding to suppress warnings relative to locals that hide variable
  • incomplete-switch to suppress warnings relative to missing entries
    in a switch statement (enum case)
  • nls to suppress warnings relative to non-nls string literals
  • null to suppress warnings relative to null analysis
  • restriction to suppress warnings relative to usage of discouraged or
    forbidden references
  • serial to suppress warnings relative to missing serialVersionUID
    field for a serializable class
  • static-access to suppress warnings relative to incorrect static
    access
  • synthetic-access to suppress warnings relative to unoptimized
    access from inner classes
  • unchecked to suppress warnings relative to unchecked operations
  • unqualified-field-access to suppress warnings relative to field
    access unqualified
  • unused to suppress warnings relative to unused code

List for Indigo adds:

  • javadoc to suppress warnings relative to javadoc warnings
  • rawtypes to suppress warnings relative to usage of raw types
  • static-method to suppress warnings relative to methods that could be declared as static
  • super to suppress warnings relative to overriding a method without super invocations

List for Juno adds:

  • resource to suppress warnings relative to usage of resources of type Closeable
  • sync-override to suppress warnings because of missing synchronize when overriding a synchronized method

Kepler and Luna use the same token list as Juno (list).

Others will be similar but vary.

What do @SuppressWarnings(deprecation) and (unused) mean in Java?

The @SuppressWarnings annotation disables certain compiler warnings. In this case, the warning about deprecated code ("deprecation") and unused local variables or unused private methods ("unused"). This article explains the possible values.

Unnecessary @SuppressWarnings(unused)

In the code in your question, the @SuppressWarnings("unused") annotation is unnecessary because the method is either overriding another method from a superclass or implementing an interface. Even if you don't actually use the whatever parameter it's mandatory to declare it, otherwise the @Override annotation will produce an error (you'd be changing the signature of the overridden method if you removed the parameter.)

In some older versions of Eclipse the code as shown would not cause a warning, but in more recent releases it does. I believe it's a valid warning, and I'd rather remove the @SuppressWarnings("unused") in this case.

@SuppressWarnings vs @SuppressLint

There are actually two lints: one belongs to the compiler, so is Java-specific, and one belongs to Google and is Android-specific.

If your warning is about something in Java that isn't specific to Android, it's suppressed with @SuppressWarnings, and if it's Android-specific, it's suppressed with @SuppressLint.

Android Lint Warnings

Lint warnings are listed here: http://tools.android.com/tips/lint-checks

So let's say you have a warning about missing permissions, and the warning description starts off "This check scans through your code and libraries and looks at the APIs being used, and checks this against the set of permissions required to access those APIs." In the lint warnings page linked above, we find this:

MissingPermission


Summary: Missing Permissions

Priority: 9 / 10
Severity: Error
Category: Correctness

This check scans through your code and libraries and looks at the APIs being used, and checks this against the set of permissions required to access those APIs. If the code using those APIs is called at runtime, then the program will crash.

Furthermore, for permissions that are revocable (with targetSdkVersion 23), client code must also be prepared to handle the calls throwing an exception if the user rejects the request for permission at runtime.

So to suppress this, we put this annotation on the code:

@SuppressLint("MissingPermission")

Compiler Warnings

Let's say we find this warning:

"Unchecked cast: 'java.lang.Object' to 'java.lang.Integer' ..."

If you are reading this in hover popup in Android Studio, there is a More... link at the end. When you click the More... link, the text expands and you find this at the bottom:

"Hint: Pass -Xlint:unchecked to javac to get more details."

This tells you that you would use "unchecked" in the annotation like this:

@SuppressWarnings("unchecked")

For a list of compiler warnings, run javac -X:

C:\>javac -X
-Xlint Enable recommended warnings
-Xlint:{all,auxiliaryclass,cast,classfile,deprecation,dep-ann,divzero,empty,fallthrough,finally,options,overloads,overrides,path,processing,rawtypes,serial,static,try,unchecked,varargs,-auxiliaryclass,-cast,-classfile,-deprecation,-dep-ann,-divzero,-empty,-fallthrough,-finally,-options,-overloads,-overrides,-path,-processing,-rawtypes,-serial,-static,-try,-unchecked,-varargs,none} Enable or disable specific warnings
.
.
.

Those are the values that you can use in @SuppressWarnings.



Related Topics



Leave a reply



Submit