2014-10-19 73 views
2
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<>(); 
    } 
} 

在上面的代码中,如果该类被制作为静态,它将正常工作! 为什么没有静态关键字是不可能的?

+1

这与泛型没有任何关系,只是说。 – Smutje 2014-10-19 14:20:31

+0

[Java内部类和静态嵌套类]的可能重复(http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class) – Smutje 2014-10-19 14:21:01

+0

您的类型参数''在内部类从外部阶层隐藏''。无论如何,你应该改正你的例子(你试图创建非静态的内部类,而不使用任何外部类的实例)。 – Pshemo 2014-10-19 14:24:23

回答

4

一般来说,如果有也不会在外部类的任何泛型类型,你可以这样写代码:

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类的实例也取决于其外部类(ES)泛型类型。这就是为什么在创建参考,你需要写它明确地使用与泛型类型外类作为

Outer<String> outer = new Outer<>(); 
Outer<String>.Inner inner = outer.new Inner(); 
^^^^^^^^^^^^^ 

或明确地说,内部类是外部类使用raw type(不建议使用这种)像

Outer.Inner inner = outer.new Inner(); 

因此,为了使你的代码工作,你需要:

  1. 附加Ø子类的类型(最好与它的类型一致)

  2. 在外部类的实例上调用内部类的构造函数(就像非静态方法不能在没有实例的情况下被调用,必须创建非静态(内部)类)使用外部类的实例)

    InnerClassGenerics<String>.Innerclasss<String> innerclass = icg.new Innerclasss<>(); 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^         ^^^^ 
         point 1           point 2 
    

你也不应该放弃在嵌套类相同的名字,以泛型类型和其外部类,像在这种情况下

public class InnerClassGenerics<T>{ 
    class Innerclasss<T>{ 
     ... 
    } 
} 

因为TInnerclasss隐藏其外部类InnerClassGenericsT(不,它会导致当前的问题,但它可以让你的生活困难后)。

+0

精确解释..谢谢! – Terminator 2014-10-19 17:44:24

+0

@Terminator不客气:) – Pshemo 2014-10-19 17:45:19

-1

所以你有这个类的定义,它不会编译,因为你有两种类型叫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编译。

+1

那么,这可能是Java 7的一个问题,但InnerClass inner仍然会导致编译器错误。它不应该是'OuterClass .InnerClass '? – Tom 2014-10-19 14:25:04

+0

@Tom在Java8(Eclipse)上编译得很好 – msrd0 2014-10-19 14:26:39

+0

上面的代码是抛出编译时错误。 (无法对非静态类型的InnerClass进行静态引用) – Terminator 2014-10-19 14:29:13

相关问题