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

Georgiy Rakov georgiy.rakov at oracle.com
Tue Apr 12 11:02:37 UTC 2016


Indeed, it's possible, the sample you provided compiles successfully!

Yes, it really looks that service interface can be an inner class.

Thanks o lot,
Georgiy.

On 11.04.2016 23:20, Peter Levart wrote:
> Hi Georgiy,
>
> It turns out that an inner class can be extended by a non-inner class. 
> See JLS "8.8.7.1. Explicit Constructor Invocations":
>
>     "Qualified superclass constructor invocations begin with a Primary 
> expression or an ExpressionName. They allow a subclass constructor to 
> explicitly specify the newly created object's immediately enclosing 
> instance with respect to the direct superclass (§8.1.3). This may be 
> necessary when the superclass is an inner class."
>
> I've never done that in code before, but it seems it works:
>
>     public class Outer {
>         public class Inner {}
>     }
>
>     public class Sub extends Outer.Inner {
>         Sub() {
>             new Outer().super();
>         }
>     }
>
>
>
> ...so, it seems that a service interface can be an inner class.
>
>
> Regards, Peter
>
>
> On 04/11/2016 12:42 PM, Georgiy Rakov wrote:
>> 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.
>
> I see. But that could be deduced since service implementations is 
> either the same class or a subtype of service interface (a subclass of 
> or a class implementing service interface). And a subclass of an inner 
> class is
>
>>
>> Thanks,
>> Georgiy.
>>> Regards, Peter
>>>
>>
>



More information about the jigsaw-dev mailing list