6

Good afternoon all,

I was wondering what's the reason that

public class test<T> {
    T[] backing_array;

    public void a(int initial_capacity) {
        @SuppressWarnings("unchecked")
        T[] backing_array = (T[]) new Object[initial_capacity];
        this.backing_array = backing_array;
    }
}

is valid but

public class test<T> {
    T[] backing_array;

    public void b(int initial_capacity) {
        @SuppressWarnings("unchecked")
        this.backing_array = (T[]) new Object[initial_capacity];
    }
}

is a syntax/compiler error?

What's the reason that we have to use an intermediary variable for @SuppressWarnings("unchecked") ?

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • mmm..same here but if you moved the SuppressWarning to before the class block, it is fine though.. +1 for this. – Jasonw Jan 31 '12 at 07:58
  • @Jasonw, from http://docs.oracle.com/javase/7/docs/api/java/lang/SuppressWarnings.html: _"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."_ – Jaime Hablutzel Jul 14 '15 at 22:18

3 Answers3

5

Because you can only annotate:

  • classes
  • methods
  • variables
  • parameters
  • packages

You cannot annotate expressions or statements.

Krizz
  • 11,362
  • 1
  • 30
  • 43
5

the @SuppressWarnings("unchecked") is applied on the scope of the declaration and assignment right after it. It can be assigned to functions' scope, or a specific variable's assignment.
In your first example, it is applied on the local variable. In the 2nd example, you're trying to apply it on an assignment of a field that was already declared.

See that this also doesn't compile:

public class Test<T> {

    public void a(int initial_capacity) {
        T[] backing_array;
        @SuppressWarnings("unchecked")
        backing_array = (T[]) new Object[initial_capacity];
    }
}

and this has no effect on warnings:

public class Test<T> {

    public void a(int initial_capacity) {
        @SuppressWarnings("unchecked")
        T[] backing_array;
        backing_array = (T[]) new Object[initial_capacity];
    }
}

In short, SuppressWarnings cannot be applied on a variable's throughout its scope. It's applied on an assignment+decleration (for variables) or on the entire method's scope when applied on a method.

Enrico
  • 621
  • 1
  • 4
  • 12
1

Compiles OK for me (simplified to remove irrelevant code):

public static class Test<T> {
    T[] array;

    public void a() {
        @SuppressWarnings("unchecked")
        T[] a = (T[]) new Object[1];
        this.array = a;
    }

    @SuppressWarnings("unchecked")
    public void b() {
        this.array = (T[]) new Object[1];
    }
}

The only observation of note is that the @SuppressWarnings goes on the method rather than the code line in b() due to the suppression being on a field assignment rather than local variable assignment

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • deleted an earlier comment, which was written prior to your edit :) +1 for a nice explanation – posdef Jan 31 '12 at 08:03
  • @Bohemian but for my case there are other statements in the method `b` and I would like to keep SuppressWarnings as scoped as possible. – Pacerier Jan 31 '12 at 08:10