package generics;
public class InnerClassGenerics{
class Innerclasss{
}
public static void main(String[] args) {
InnerClassGenerics icg=new InnerClassGenerics();
Innerclasss innerclass=icg.new Innerclasss();
}
}
以上代码是可能的并且编译得很好!!!
为什么以下代码无法编译,是否可以参数化内部类?
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<>();
}
}
在上面的代码中,如果该类是静态的,它可以正常工作! 为什么没有静态关键字是不可能的?
答案 0 :(得分:3)
通常情况下,如果外部类不存在任何泛型类型,则可以编写如下代码:
Outer outer = new Outer();
Inner inner = outer.new Inner();
因为内部类中的每个方法都已经知道它应该使用什么类型。
但是当外部类使用泛型类型时,情况稍微复杂一些。由于内部类可以访问其外部类(或类)的所有成员,因此还需要了解外部类中使用的泛型类型,以确保操作泛型值时的类型安全。
看看这段代码:
class Outer<T> {
private T someValue;
class Inner {
T getOuterValue(){
return someValue;
}
void setOuterValue(T value){
someValue=value;
}
}
//rest of code
}
这意味着Inner
类的实例也依赖于其外部类的泛型类型。这就是为什么在创建对内部类的引用时,需要通过将其写为
Outer<String> outer = new Outer<>();
Outer<String>.Inner inner = outer.new Inner();
^^^^^^^^^^^^^
或明确地说外部类使用raw type(不鼓励),如
Outer.Inner inner = outer.new Inner();
因此,要使代码正常工作,您需要:
添加外部类类型(最好使用其泛型类型)
在外部类的实例上调用内部类的构造函数(就像在没有实例的情况下可以调用非静态方法一样,必须使用外部类实例创建非静态(内部)类)
InnerClassGenerics<String>.Innerclasss<String> innerclass = icg.new Innerclasss<>();
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
point 1 point 2
此外 不应该为嵌套类及其外部类中的泛型类型指定相同的名称 ,就像在这种情况下一样
public class InnerClassGenerics<T>{
class Innerclasss<T>{
...
}
}
因为来自T
的Innerclasss
隐藏 T
来自其外部类InnerClassGenerics
(不是它会导致当前问题,但它可以使您的生活困难以后)。
答案 1 :(得分:-1)
所以你有这个类定义,它不会编译,因为你有2个类型叫T
。使它像这样,它将编译:
public class OuterClass <O>
{
public class InnerClass <I>
{
}
}
另外,请注意您正在从静态方法实例化非静态类。您完成的代码应如下所示:
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();
}
}
上面的代码需要Java 8才能编译。