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-EvenList 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];