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