本文介绍了是否可以使用参数化通用内部类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  package generics; 
public class InnerClassGenerics {
class Innerclasss {

}
public static void main(String [] args){
InnerClassGenerics icg = new InnerClassGenerics() ;
Innerclasss innerclass = icg.new Innerclasss();




$ b $ p
$ b

上面的代码是可能的并且编译得很好!!!






为什么下面的代码不能编译,并且可能参数化内部类?

  package generics; 
public class InnerClassGenerics< T> {
class Innerclasss< T> {

}
public static void main(String [] args){
InnerClassGenerics< ;字符串> icg = new InnerClassGenerics<>();
Innerclasss< String> innerclass = new Innerclasss<>();




$ b $ p
$ b

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

解决方案

通常情况下,如果外层没有任何泛型类型类可以编写如下代码:

  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;
}
}
//其余代码
}

这意味着 Inner 类的实例也依赖于它的外部类(es)的泛型类型。这就是为什么在创建内部类的引用时,您需要将外部类与泛型类型明确地一起使用,方法是将它写为

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

或明确地说外部类使用(这是令人沮丧的)像

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






因此,要使代码正常工作,您需要:


  1. 添加外部类型(最好使用泛型)

  2. >

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

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


另外, 不应该为generic类嵌套类及其外部类 ,就像在这种情况下一样

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

,因为 T 来自 Innerclasss 隐藏 <$ c $从它的外部类 InnerClassGenerics (不是它会导致当前的问题,但它可能会让你的生活稍后变得困难)。


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:

  1. add outer class type (preferably with its generic type)

  2. 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).

这篇关于是否可以使用参数化通用内部类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 08:40