United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6945418 Project Coin: Simplified Varargs Method Invocation
JDK-6945418 : Project Coin: Simplified Varargs Method Invocation

Details
Type:
Enhancement
Submit Date:
2010-04-20
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
tools
OS:
generic
Sub-Component:
javac
CPU:
unknown
Priority:
P2
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

Description
Quoting from project coin proposal at the following URL:

http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000316.html

"When a programmer tries to invoke a varargs (variable
arity) method with a non-reifiable varargs type, the compiler currently
generates an "unsafe operation" warning. This proposal moves the warning
from the call site to the method declaration."

BEFORE:

  static <T> List<T> asList(T... elements) { ... }

  static List<Callable<String>> stringFactories() {
    Callable<String> a, b, c;
    ...
    // Warning: "uses unchecked or unsafe operations"
    return asList(a, b, c);
  }

AFTER (1):

  // Warning: "enables unsafe generic array creation"
  static <T> List<T> asList(T... elements) { ... }

  static List<Callable<String>> stringFactories() {
    Callable<String> a, b, c;
    ...
    // Warning: "uses unchecked or unsafe operations"
    return asList(a, b, c);
  }

AFTER (2):

  @SuppressWarnings("generic-varargs")
  static <T> List<T> asList(T... elements) { ... } //no warning

  static List<Callable<String>> stringFactories() {
    Callable<String> a, b, c;
    ...
    // no warning
    return asList(a, b, c);
  }

                                    

Comments
EVALUATION

Sounds a sensible proposal. Vararg warnings have been historically very hard to cope with. However there are a few technical point of this proposal that deserve further discussions: the proposal in [1] seem to suggest the idea that it is possible to realize that a vararg method is unsafe simply by looking at its signature. More specifically, the proposed rule is something along the following lines:

"When compiling a varargs method that could accept a non-reifiable
varargs type, the compiler should generate a warning on the varargs method
declaration. A varargs type is non-reifiable if it contains a type variable
anywhere in its signature."

The following example shows that this is not enough:

void m(List<String>... o) {
   Object[] arr = o;
   o[0] = new ArrayList<Integer>();
   List<String> ls = o[0]; //CCE!!
}

The spec should be made stricter, by mandating warnings for vararg method with a non-reifiable element type, where non-reifiable is defined the JLS way (see JLS 3rd 4.7).

Note also that there are cases in which suppressing the call-site warning might be dangerous --- esp. if the called vararg method has been compiled in a separate compilation unit; in those cases, there will be no unchecked warning on the call-site (as per proposal), but there could still be a CCE at runtime (e.g. because the vararg method we compiled against was unsafe).

For this reason we think it would be better to leave call-site warnings as they are now, but to give users a way to disable those warnings (e.g. via the @SuppressWarnings("varargs-unchecked") annotation).


[1] - http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000316.html
                                     
2010-04-20
SUGGESTED FIX

A webrev of this fix is available at the following URL:
http://hg.openjdk.java.net/jdk7/tl/langtools/rev/46cf751559ae
                                     
2010-06-11



Hardware and Software, Engineered to Work Together