package generics;
public class InnerClassGenerics{
class Innerclasss{
}
public static void main(String[] args) {
InnerClassGenerics icg=new InnerClassGenerics();
Innerclasss innerclass=icg.new Innerclasss();
}
}
Above code is possible and compiles fine!!!
Why is the below code doesn't compile, and is it possible to parametrize inner classes?
package generics;
public class InnerClassGenerics<T>{
class Innerclasss<T>{
}
public static void main(String[] args) {
InnerClassGenerics<String> icg=new InnerClassGenerics<>();
Innerclasss<String> innerclass=new Innerclasss<>();
}
}
In the above code if the class is made as static it works fine!!! Why is it not possible without static keyword?
Normally if there wouldn't be any generic type on outer class you could write code like this:
Outer outer = new Outer();
Inner inner = outer.new Inner();
because each method in inner class already knows what types should it be using.
But situations is little more complicated when outer class uses generic types. Since inner class have access to all members of its outer class (or classes), it also needs to know about generic type used in outer class(es) to ensure type safety while manipulating generic values.
Take a look at this code:
class Outer<T> {
private T someValue;
class Inner {
T getOuterValue(){
return someValue;
}
void setOuterValue(T value){
someValue=value;
}
}
//rest of code
}
This means that instance of Inner
class also depends on generic type from its outer class(es). That is why while creating reference to inner class you need to explicitly use outer class with generic type by writing it as
Outer<String> outer = new Outer<>();
Outer<String>.Inner inner = outer.new Inner();
^^^^^^^^^^^^^
or explicitly say that outer class uses raw type (which is discouraged) like
Outer.Inner inner = outer.new Inner();
So to make your code work you need to:
add outer class type (preferably with its generic type)
invoke constructor of inner class on instance of outer class (just like non-static methods can't be invoked without instance, non-static (inner) classes must be created using outer class instance)
InnerClassGenerics<String>.Innerclasss<String> innerclass = icg.new Innerclasss<>(); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ point 1 point 2
Also you shouldn't give same names to generic types in nested classes and its outer classes, like in this case
public class InnerClassGenerics<T>{
class Innerclasss<T>{
...
}
}
because T
from Innerclasss
hides T
from its outer class InnerClassGenerics
(not that it causes current problem, but it can make your life difficult later).
So you have this class definition, and it won't compile because you have 2 types called T
. Make it like this and it'll compile:
public class OuterClass <O>
{
public class InnerClass <I>
{
}
}
Also, notice that you are instantiating a non-static class from a static method. You complete code should look like this:
public class OuterClass <O>
{
public static class InnerClass <I>
{
}
public OuterClass ()
{
}
public InnerClass<O> getInnerClass ()
{
return new InnerClass<O>();
}
public static void main (String[] args)
{
OuterClass<String> outer = new OuterClass<>();
InnerClass<String> inner = outer.getInnerClass();
}
}
The code above needs Java 8 to compile.
来源:https://stackoverflow.com/questions/26451400/is-it-possible-to-use-parametrize-generic-inner-classes