Anonymous class with parameterized super type, constructor formal parameters
Srikanth
srikanth.adayapalam at oracle.com
Tue Jun 23 08:35:05 UTC 2015
On Thursday 11 June 2015 09:23 PM, Georgiy Rakov wrote:
> 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.
I believe what you are observing is the intended behaviour which is not
contrary in reality to the documented behaviour.
You are inspecting the parameters at run time at which point due to
erasure the relevant information is lost. The super
type of the anonymous class here is NOT (the erased) Test7A, but is
Test7A<String> - and when viewed in that light,
the assertion you cite holds true.
Thanks
Srikanth
>
> 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/20150623/bad79ff8/attachment.html>
More information about the compiler-dev
mailing list