JDK-8069254 : Warning issued despite @SafeVarargs annotation on constructor
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u25
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2015-01-14
  • Updated: 2015-06-04
  • Resolved: 2015-01-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b48Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux example.com 3.18.1-desktop-3.mga5 #1 SMP Tue Dec 30 22:09:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
Consider the following code:


import java.util.Iterator;
import java.util.LinkedList;

public class Test {
        static class Foo<T> {
                @SafeVarargs
                public Foo(T... args) {
                }
        }

        public static void main(String[] args) {
                Foo<String> foo0 = new Foo<>("0", "1"); // Clear
                Foo<String> foo1 = new Foo<String>("0", "1"); // Clear

                Iterator<String> i = new LinkedList<String>().iterator();

                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                Foo<Iterator<String>> foo3 = new Foo<Iterator<String>>(i, i); // Clear
        }
}


ECJ compiles this code with no warnings. When compiled with Oracle JDK or OpenJDK, though, a single warning is issued:

Test.java:19: warning: [unchecked] unchecked generic array creation for varargs parameter of type Iterator<String>[]
                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                                             ^
1 warning


There seems to be some relation to the use of the diamond operator. Also, the behavior w.r.t. the warning seems inconsistent when compared with the other three cases, especially with the `... foo0 = ...' case.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the following code:

import java.util.Iterator;
import java.util.LinkedList;

public class Test {
        static class Foo<T> {
                @SafeVarargs
                public Foo(T... args) {
                }
        }

        public static void main(String[] args) {
                Foo<String> foo0 = new Foo<>("0", "1"); // Clear
                Foo<String> foo1 = new Foo<String>("0", "1"); // Clear

                Iterator<String> i = new LinkedList<String>().iterator();

                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                Foo<Iterator<String>> foo3 = new Foo<Iterator<String>>(i, i); // Clear
        }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No warnings should be issued by the compiler
ACTUAL -
Test.java:19: warning: [unchecked] unchecked generic array creation for varargs parameter of type Iterator<String>[]
                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                                             ^
1 warning


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Test.java:19: warning: [unchecked] unchecked generic array creation for varargs parameter of type Iterator<String>[]
                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                                             ^
1 warning


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Iterator;
import java.util.LinkedList;

public class Test {
        static class Foo<T> {
                @SafeVarargs
                public Foo(T... args) {
                }
        }

        public static void main(String[] args) {
                Foo<String> foo0 = new Foo<>("0", "1"); // Clear
                Foo<String> foo1 = new Foo<String>("0", "1"); // Clear

                Iterator<String> i = new LinkedList<String>().iterator();

                Foo<Iterator<String>> foo2 = new Foo<>(i, i); // Warning
                Foo<Iterator<String>> foo3 = new Foo<Iterator<String>>(i, i); // Clear
        }
}

---------- END SOURCE ----------


Comments
I've also reproduced the reported behavior. The inconsistency in warning reporting is certainly suspicious and could be caused by checks inside javac being done in an improper order; reassigning to a different engineer.
21-01-2015

Not sure what Pardeep meant above but I can reproduce this with JDK8u25, 8u40 and 9. Command line compilation is: javac -d . Test.java -Xlint:unchecked
20-01-2015

Checked this with JDK8u25, 7u72, 8u40 and 9 and couldn't reproduce.
19-01-2015