Java 内部类的泛型数组创建

Java 内部类的泛型数组创建,java,generics,inner-classes,Java,Generics,Inner Classes,我创建数组的那一行给了我一个通用数组创建警告。 处理这个问题的好方法是什么 public class Foo<T> { void someMethod() { Point[] points = new Point[3]; } class Point { float x, y; } } 公共类Foo{ void方法(){ 点[]点=新点[3]; } 类点{ 浮动x,y; } } 在我看来,你的点类只是用来存放x和y,

我创建数组的那一行给了我一个
通用数组创建
警告。 处理这个问题的好方法是什么

public class Foo<T> {

    void someMethod() {
        Point[] points = new Point[3];
    }

    class Point {
        float x, y;
    }
}
公共类Foo{
void方法(){
点[]点=新点[3];
}
类点{
浮动x,y;
}
}

在我看来,你的
类只是用来存放
x
y
,没有理由隐藏对
Foo
实例的引用。如果这是正确的,那么
Point
应该是嵌套类,而不是内部类。添加
static
关键字:

public class Foo<T> {

    void someMethod() {
        Point[] points = new Point[3];
    }

    static class Point {
        float x, y;
    }
}
公共类Foo{
void方法(){
点[]点=新点[3];
}
静态类点{
浮动x,y;
}
}

首先,让我们找出Java认为
新点[3]
创建泛型数组,而
似乎是非泛型类的原因。这是因为
Point
是一个非静态类,这意味着编译器嵌入了对
Foo
的隐藏引用。该类在Java中看起来如下所示:

class Foo$Point<T> {
    Foo<T> _hidden_Foo;
    float x, y;
}

内部类还可以访问其外部类的泛型类型。假设我们有

class Foo<T> {

    class Point {
        float x, y;
        T value;
        T getValue(){
            return value;
        }
    }
}
我们可以基于其外部实例创建其内部类的实例,如

Point p = f.new Point();
// or 
//Foo<String>.Point p = f.new Point 
// if we are creating it for instance outside of Foo class
相当于

Point[] points = new Foo<T>.Point[3];
//  Foo<T> is type of outer instance on which you are invoking new
现在呢

Point[] points = new Point[3]; 
我会很好的


Point
是一个非静态的内部类。因此,自行编写的
Point
表示
Foo.Point
,一种参数化类型。您不能执行
新建点[3]
(与
新建Foo.Point[3]
相同),原因与您不能执行
新建ArrayList[3]
相同

让我们打个比方,问问你想做什么

ArrayList<T>[] lists = new ArrayList<T>[3];
ArrayList[]列表=新的ArrayList[3];
有两种方法:

  • 创建原始类型的数组:

    ArrayList[]列表=新的ArrayList[3]

  • 或者,如果不喜欢原始类型,请创建通配符参数化类型的数组:

    ArrayList[]列表=(ArrayList[])新的ArrayList[3]

  • 因此,在我们的案例中,我们有两种相同的解决方案:

  • 创建原始类型的数组。但是,什么是原始类型?这不是我们发现的
    ;因为这是隐式参数化的。相反,我们需要用外部类名显式限定名称:
    Foo.Point

    Point[]points=新的Foo.Point[3]

  • 或者,如果不喜欢原始类型,请创建通配符参数化类型的数组:

    Point[]列出=(Point[])新的Foo.Point[3]


  • 静态类点{…
    。看起来您的内部类只是用来存放
    x
    y
    ,并不需要指向
    Foo
    实例的隐藏指针。如果我是对的,那么它应该是嵌套类而不是内部类。@ajb这应该是答案(因为这是答案)。有趣的是,为什么
    Point p=new Point()
    编译得很好,而
    Point[]points=new points[3]
    编译得不好。@Pshemo-Even
    List points=new ArrayList()
    编译很好,限制只适用于数组。我不确定
    Foo$Point
    。如果我没有弄错的话,它将在
    Point
    中声明
    T
    ,这将不同于
    Foo
    。你有任何来源可以证实它吗?@Pshemo我想
    Foo$Point
    中的
    T
    将d独立于
    Foo
    中的
    T
    。我把
    放在
    中,以说明为什么
    Point
    成为泛型,假装它是一个顶级类。我并不想暗示Java编译器会生成与此完全相同的代码,只是(1)将引用外部上下文的
    Foo
    ,(2)这就是
    类被视为泛型的原因。
    Point[] points = new Foo<T>.Point[3];
    //  Foo<T> is type of outer instance on which you are invoking new
    
    Point[] points = new Foo.Point[3];// we got rid of <T>
    
    List<Point> points = new ArrayList<>();
    
    static class Point {
        float x, y;
    }
    
    Point[] points = new Point[3]; 
    
    ArrayList<T>[] lists = new ArrayList<T>[3];