Compilation fails because anonymous class constructor formal parameter has inaccessible type

Georgiy Rakov georgiy.rakov at oracle.com
Thu Jul 23 13:47:46 UTC 2015



On 22.07.2015 20:12, Pawel wrote:
>
>
> On Jul 22, 2015, at 7:03 AM, Georgiy Rakov <georgiy.rakov at oracle.com 
> <mailto:georgiy.rakov at oracle.com>> wrote:
>
>> Hello,
>>
>> let's consider following example:
>>
>>     class Test18_2 {private static class MyClass {}public static
>>     MyClass v1 = new MyClass();Test18_2(MyClass mc) {}}public class
>>     Test18 {public static void main(String[] args) {new
>>     Test18_2(Test18_2.v1){};}}
>>
>>
>> this example fails to compile on JDK9b73 with following error:
>>
>>     Error:(9, 34) java: Test18_2.MyClass has private access in Test18_2
>>
>> However according to my understanding compilation should succeed as 
>> per assertion jls-15.9.5.1-200:
>>
>>     Note that it is possible for the signature of the anonymous
>>     constructor to refer to an inaccessible type (for example, if
>>     such a type occurred in the signature of the superclass
>>     constructor |cs|). This does not, in itself, cause any errors at
>>     either compile-time or run-time.
>>
>> It seems to be a javac bug. Could you please tell if you agree.
>
> This seems to say that it is the signature of a constructor that 
> shouldn't cause any errors. I believe the error is coming from the 
> access of Test18.v1, as its type can not be accessed. That would fail 
> outside of being used as a constructor argument, so it shouldn't be 
> allowed if used as one either.
According to my understanding Test18_2.v1 is supposed to be used outside 
too despite the fact that the type of it is inaccessible. The error I'm 
talking about seems to be caused by the fact that the class being 
instantiated is anonymous. Provided it's not anonymous, compilation 
succeeds! Namely following code compiles successfully (just removing 
curly brackets from instance creation expression):

    class Test18_2 {private static class MyClass {}public static MyClass
    v1 = new MyClass();Test18_2(MyClass mc) {}}public class Test18
    {public static void main(String[] args) {new Test18_2(Test18_2.v1);}}

So I believe that this is anonymous constructor signature which causes 
this error. Please note that anonymous class itself doesn't have access 
to MyClass, for instance declaring any method having MyClass in its 
signature within anonymous class would naturally cause compilation 
error, for instance:

    new Test18_2(Test18_2.v1) { private MyClass foo(){ return null; } }

Thus anonymous class constructor which is declared implicitly could have 
the same reason to cause compilation error if it has any inaccessible 
type within its signature. According to my understanding it's the 
assertion I pointed out above which allows anonymous classes to compile 
successfully in such cases. It seems that javac merely do not take this 
assertion into account.

As I said above anonymous constructor is declared implicitly, that is it 
cannot be seen in the code, instead it's generated by javac 
automatically during compilation if I understand it correctly. And it 
"copies" formal parameters from corresponding super type constructor. 
This is described in JLS 15.9.5.1.

Thanks,
Georgiy.
>
>>
>> Thanks,
>> Georgiy.
>> <Test18.java>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150723/aaf82665/attachment.html>


More information about the compiler-dev mailing list