Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot find type parameter if it is an inner class of the subclass in Java

Tags:

java

Why does the following code have a compile error:

Foo.java:

public abstract class Foo<T> {
    public abstract T getInner();
}

MyFoo.java:

public class MyFoo extends Foo<MyFooInner> {
    public static class MyFooInner {
    }
    public MyFooInner getInner() {
        return new MyFooInner();
    }
}

Compiling the second class results in:

MyFoo.java:1: cannot find symbol
symbol: class MyFooInner
public class MyFoo extends Foo<MyFooInner> {
                               ^
1 error

Is there a way around this problem besides putting the inner class in its own file?

like image 793
jonderry Avatar asked Sep 27 '11 21:09

jonderry


People also ask

Is inner class subclass Java?

inner classes are in the same file, whereas subclasses can be in another file, maybe in another package. You cannot get an instance of an inner class without an instance of the class that contains it.

How do you check if an object is a certain subclass?

The java “instanceof” operator is used to test whether the object is an instance of the specified type (class or subclass or interface). It is also known as type comparison operator because it compares the instance with type. It returns either true or false.

How do you find the value of an inner class?

Accessing the Private Members Write an inner class in it, return the private members from a method within the inner class, say, getValue(), and finally from another class (from which you want to access the private members) call the getValue() method of the inner class.


2 Answers

Use the following notation:

public class MyFoo extends Foo<MyFoo.MyFooInner> {...

UPDATE: Static nested classes are effectively a top level class as specified here:

A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

So, the only way you can refer to a static nested class is mentioning its parent class somewhere. Otherwise it is a reference to an imported class or to a class within the same package.

UPDATE: To explain it even more, another way to reference the class is to import it like this:

import my.package.MyFoo.MyFooinner;

public class MyFoo extends Foo<MyFooInner> {...
like image 73
Andrey Adamovich Avatar answered Oct 14 '22 09:10

Andrey Adamovich


To build on @Andrey Adamovich's answer, the reason for this is that types identified in a class declaration must make sense to members outside that class. This is the same as if I had written the following in another class file:

MyFooInner mfi = new MyFooInner()

This would not compile because that class wouldn't know what MyFooInner was - I would either need to qualify it by writing MyFoo.MyFooInner or else use import MyPackage.MyFoo.MyFooInner;. The same logic applies to class declarations.

For the same reason, nested classes that are declared private cannot be used in the parent class's declaration at all.

like image 30
Paul Bellora Avatar answered Oct 14 '22 10:10

Paul Bellora