Questionable compilation failure

Peter Levart peter.levart at gmail.com
Fri Sep 20 00:36:05 PDT 2013


Hi Remi,

Regarding the javac message and it's clearness. I think the message is 
more clear if you think of invoking constructors of non-static nested 
classes is analogue to invoking instance methods of outer instance. For 
example:

public class SupplierTest {

     class Concrete<T> implements Supplier<Concrete<T>> {
         @Override
         public Concrete<T> get() {
             return this;
         }
     }

     <T> Concrete<T> createConcrete() {
         return new Concrete<>();
     }

     /* static */ class Test  {
         void doSomething() {
             createConcrete();   // <-----
         }
     }
}


You can pass explicit SupplierTest.this. before the method name or it 
can be unqualified (if there's not such method in the Test class 
itself). The compiler error in case Test was static (or interface with 
default method) is the same:

java: non-static method <T>createConcrete() cannot be referenced from a 
static context



Regards, Peter

On 09/20/2013 08:58 AM, Peter Levart wrote:
>> And to come back to the error message, Eclipse error message is more 
>> clear:
>> "No enclosing instance of type SupplierTest is accessible. Must 
>> qualify the allocation with an enclosing instance of type 
>> SupplierTest (e.g. x.new A() where x is an instance of SupplierTest)."
>
> I agree that Eclipse is more clear and I don't object your 
> explanation, but I think Sebastian was surprised because the following 
> code:
>
> public class SupplierTest {
>
>     class Concrete<T> implements Supplier<Concrete<T>> {
>         @Override
>         public Concrete<T> get() {
>             return this;
>         }
>     }
>
>     class Test  {
>         void doSomething() {
>             new Concrete<String>();   // <-----
>         }
>     }
> }
>
>
> ...does compile. You see, there's no explicit reference to 
> SupplierTest.this. before constructor of Concrete. And If you change 
> the above to:
>
>
> public class SupplierTest {
>
>     class Concrete<T> implements Supplier<Concrete<T>> {
>         @Override
>         public Concrete<T> get() {
>             return this;
>         }
>     }
>
> *static* class Test  {
>         void doSomething() {
>             new Concrete<String>();   // <-----
>         }
>     }
> }
>
>
> ...you get the same message from javac as with nested 
> interface/default method.
>
>
> Regards, Peter
>
>>
>> cheers,
>> Rémi
>>



More information about the lambda-dev mailing list