Anonymous class with parameterized super type, constructor formal parameters
Georgiy Rakov
georgiy.rakov at oracle.com
Thu Jun 11 15:53:29 UTC 2015
Hello,
assertion jls-15.9.5.1-100-A.1 specifies:
The actual arguments to the class instance creation expression are
used to determine a constructor |cs| of S, using the same rules as
for method invocations (§15.12
<https://baloo.ru.oracle.com/jenkins/job/jck9-lang/lastSuccessfulBuild/artifact/build/out/htmlout/jls-15.html#jls-15.12>).
/_*The type of each formal parameter of the anonymous constructor
must be identical to the corresponding formal parameter of
*_//_*|cs|*_/.
I'd like to point to the emphasized part of the assertion above which
states that the formal parameters of the anonymous class constructor are
identical to those of the corresponding super class constructor.
However let's consider following example:
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.stream.Stream;
class Test7A<T> {
Test7A(T t) {}
}
public class Test7 {
public static void main(String[] args) throws
NoSuchMethodException {
Test7A<String> a = new Test7A<>("a"){};
System.out.println("Diamond case:");
printlnParameters("anonymous class constructor",
a.getClass().getDeclaredConstructor(String.class));
printlnParameters("super class constructor",
a.getClass().getSuperclass().getDeclaredConstructor(Object.class));
System.out.println();
a = new Test7A<String>("a"){};
System.out.println("Explicit type arguments case:");
printlnParameters("anonymous class constructor",
a.getClass().getDeclaredConstructor(String.class));
printlnParameters("super class constructor",
a.getClass().getSuperclass().getDeclaredConstructor(Object.class));
}
static void printlnParameters(String label, Constructor c) {
Stream<String> stream =
Arrays.stream(c.getParameters()).map(p -> p.getType().toString());
System.out.println(" " + label + ": " +
Arrays.toString(stream.toArray()));
}
}
The output of this program is:
Diamond case:
anonymous class constructor: [class java.lang.String]
super class constructor: [class java.lang.Object]
Explicit type arguments case:
anonymous class constructor: [class java.lang.String]
super class constructor: [class java.lang.Object]
As you can see the formal parameters for the anonymous class constructor
and those of the corresponding base class constructor are different.
Could you please tell if you consider this as a discrepancy between
javac and specification which should be fixed.
BTW: this alludes to my previous letter, that is, provided the anonymous
classes in these cases were generic and its instances were just
parameterization of those the formal parameters naturally would be
identical, I believe.
Thank you,
Georgiy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150611/72ce7916/attachment-0001.html>
-------------- next part --------------
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.stream.Stream;
class Test7A<T> {
Test7A(T t) {}
}
public class Test7 {
public static void main(String[] args) throws NoSuchMethodException {
Test7A<String> a = new Test7A<>("a"){};
System.out.println("Diamond case:");
printlnParameters("anonymous class constructor", a.getClass().getDeclaredConstructor(String.class));
printlnParameters("super class constructor",
a.getClass().getSuperclass().getDeclaredConstructor(Object.class));
System.out.println();
a = new Test7A<String>("a"){};
System.out.println("Explicit type arguments case:");
printlnParameters("anonymous class constructor", a.getClass().getDeclaredConstructor(String.class));
printlnParameters("super class constructor",
a.getClass().getSuperclass().getDeclaredConstructor(Object.class));
}
static void printlnParameters(String label, Constructor c) {
Stream<String> stream = Arrays.stream(c.getParameters()).map(p -> p.getType().toString());
System.out.println(" " + label + ": " + Arrays.toString(stream.toArray()));
}
}
More information about the compiler-dev
mailing list