Inner classes are allowed to be specified in 'uses' statement

Georgiy Rakov georgiy.rakov at oracle.com
Mon Apr 11 10:42:01 UTC 2016


Hi Peter,

On 04.04.2016 11:39, Peter Levart wrote:
> Hi Georgiy,
>
> On 04/01/2016 04:52 PM, Georgiy Rakov wrote:
>> Hello,
>>
>> currently inner classes are allowed to be specified in 'uses' 
>> statement, for instance following code is compiled successfully by 
>> JDKb111 javac:
>>
>>    a/module-info.java:
>>    module a {
>>         uses pkg.Outer.Inner;
>>    }
>>
>>    a/pkg/Outer.java:
>>    package pkg;
>>    public class Outer{ public class Inner{} }
>>
>> Spec doesn't prevent it either. However in 1.1.3 
>> <http://cr.openjdk.java.net/%7Emr/jigsaw/spec/lang-vm.html> it 
>> prevents implementations specified in 'provides' statement to be 
>> inner classes. According to my understanding inner class cannot be 
>> extended by non-inner class, for instance "public class Impl extends 
>> Outer.Inner { } " would cause:
>>
>>    error: an enclosing instance
>>    that contains Outer.Inner is required
>>    class Implem extends Outer.Inner {}
>>    ^
>>    1 error
>>
>> So could you please tell what is the purpose of allowing inner 
>> classes to be specified in 'uses' statement, there seem to be no way 
>> to create its implementation. Should it be prohibited by spec?
>>
>> The minimized testcase is attached; in order to run it please:
>> 1. unzip attached archive on Windows machine;
>> 2. rename test12\test_bat to test12\test.bat;
>> 3. modify test.bat by changing JDK_HOME variable to point to your JDK 
>> installation;
>> 4. run test.bat.
>>
>> Thank you,
>> Georgiy.
>
> Not only in 'uses' statement. It would be impossible to specify them 
> in 'provides ... with ...' statement as implementation classes too as 
> they by definition can't be instantiated without an outer instance 
> (their constructors always contain an implicit parameter - the outer 
> instance). What does compiler say for such case?
>
> a/module-info.java:
> module a {
>     exports pkg;
>     provides pkg.Service with pkg.impl.Outer.Inner;
> }
>
> a/pkg/Service.java:
> package pkg;
> public interface Service {}
>
> a/pkg/impl/Outer.java:
> package pkg.impl;
> public class Outer { public class Inner implements pkg.Service { } }
>
>
For such case jdk9b113 javac says:

    a\module-info.java:3: error: the service implementation is an inner
    class: Outer.Inner
         provides pkg.Service with pkg.impl.Outer.Inner;
                                                 ^
    1 error

As I've already said this is according to spec:

    It is a compile-time error if the service implementation named by
    the |with|clause of a |provides|statement is |abstract|, or is not
    |public|, or does not have a |public|no-args constructor, or is *an
    inner class* (JLS 8.1.3).

But spec doesn't prevent service interfaces to be inner classes.

Thanks,
Georgiy.
> Regards, Peter
>



More information about the jigsaw-dev mailing list