【问题标题】:Java Inner class compilation errorJava内部类编译错误
【发布时间】:2017-03-14 18:06:11
【问题描述】:

我正在尝试实例化一个公共的非静态内部类,但我不断收到编译错误。

我有 2 个类:一个树类和一个主类。

我最终试图实例化一个点数组,但为了这个问题,我试图只实例化一个 Point 对象。

编译错误表明

Point 无法解析为类型

我做错了什么?

树.java

public class Tree<T> {  
    public class Point<T> {
        public T position[];
    }
}

Main.java

public class Main {
    public static void main(String args[]) {
        Point<Double> point = new Tree<Point<Double>>().new Point<Double>();
    }
}

【问题讨论】:

  • Point 不存在 - Tree.Point 存在。但是您真的想要两个不同的类型参数吗?我怀疑TreePoint 不应该是通用的。
  • 例如,如果Point 不是通用的,那么您将拥有Tree&lt;Double&gt;.Point point = new Tree&lt;Double&gt;().new Point();
  • 内部类可以是公共的。这是一个项目,他给了我们代码,它使用泛型。
  • 嗯,你一定做错了,因为我的编译很好。
  • 您没有使用在Tree&lt;T&gt; 中声明的任何T,因为Point 被声明为它自己的&lt;T&gt;,它遮蔽了Tree 中的一个。换句话说,你的代码就像class Tree&lt;A&gt; { class Tree&lt;B&gt; { public B position[]; } }(这里没有使用A,所以它是多余的,你为什么还要它?)。

标签: java generics inner-classes


【解决方案1】:

我怀疑您不想为TreePoint 设置两个不同的类型参数。你写的方式,PointT遮蔽了TreeT,所以参数实际上是不同的。如果您希望它们相同,请删除内部类的T。这样外部类的T也可以在内部类中使用。

public class Tree<T> {  
    public class Point {
        public T position[];
    }

    public static void main(String args[]) {
        Tree<Double>.Point point = new Tree<Double>().new Point();
    }
}

如果你真的想要有两个不同的Ts,你可以像这样实例化一个Point。但是我强烈建议重命名其中一个类型参数以防止混淆。

Tree<Object>.Point<Double> point = new Tree<>().new Point<>();

编辑:根据cmets:

Tree<Tree<?>.Point<Double>>.Point<Double> point = new Tree<Tree<?>.Point<Double>>().new Point<>();

编辑:根据进一步的cmets

由于您希望 Tree 始终包含点,因此在这里使用泛型是没有用的。这有点取决于你想用这个类做什么,是否删除Point 之一的Tree 的类型参数。

可能性一去掉Tree的类型参数

public class Tree {  
    public class Point<T> {
        public T position[];
    }
}

如果您想从 Tree 中的方法返回 Point,您可以使用它

可能性2去掉Point的类型参数

public class Tree<T> {  
    public class Point {
        public T position[];
    }
}

如果您希望 Tree 中的方法返回 T 类型的对象,您应该这样做

【讨论】:

  • @namarino 你是对的,对不起。我编辑了我的答案,现在它可以编译了。但是你真的应该考虑在Point 类中删除T。你有什么理由为什么内部类必须有一个类型参数?
  • 好吧,我不明白为什么有人要建立这样的课程。但是如果你真的想拥有它,你可以像这样实例化一个Point Tree&lt;Tree&lt;?&gt;.Point&lt;Double&gt;&gt;.Point&lt;Double&gt; point = new Tree&lt;Tree&lt;?&gt;.Point&lt;Double&gt;&gt;().new Point&lt;&gt;();
  • 我认为您实际上并不想要Point 类型的Tree。我认为您可能想要一个由Points 类型为DoubleTree。或者您是否希望能够做与Point 不同的事情的Tree?例如。 Tree&lt;Double&gt;
  • @namarino 我再次更新了我的答案。希望对您有所帮助!
  • @SilverNak:是的,但如果没有编辑,我认为不值得点赞,并且请求点赞是 IMO 的一个坏主意。
【解决方案2】:

在声明内部类时只需省略 T 参数。

只在里面使用T,但不要尝试重新定义同名T的类型参数。

【讨论】:

  • 我不能省略泛型。
  • 如果您想使用与外部类相同的 T,那么您确实不需要需要它。如果内部类需要不同的类型参数,例如将 T 重命名为 S!
【解决方案3】:

按照 cmets 的建议:

Tree<Double>.Point<Double> point = new Tree<Double>().new Point<Double>();

但你不觉得有点多余吗?

您可以删除点的通用部分

public class Tree<T> {
    public class Point {
        public T position[];
    }
}


Tree<Double>.Point point = new Tree<Double>().new Point();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 2010-11-03
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2017-12-21
    相关资源
    最近更新 更多