【问题标题】:How to define a class that features a generic parameter which extends a class that features a generic parameter?如何定义一个具有泛型参数的类,该类扩展了具有泛型参数的类?
【发布时间】:2020-09-20 22:11:26
【问题描述】:

考虑以下情况:

public class PointCloud<T extends Point> { } 

public class PointCloud3d extends PointCloud<Point3d> { }

如何编写一个采用泛型参数T 的类,该参数是PointCloud&lt;T&gt; 的扩展?

public class PointCloudReader<T extends PointCloud> { 
    T read(String path);
}

public class PointCloudReader<T extends PointCloud<?>> {
    T read(String path);
}

这两个类定义有什么区别?

【问题讨论】:

  • 正确的做法可能真的是public class PointCloudReader&lt;P extends Point, T extends PointCloud&lt;P&gt;&gt;
  • @LouisWasserman 我实际上认为这就是我需要的答案。
  • @GiorgiTsiklauri 我有一个 JNI 项目,使用继承和泛型比单独使用 Java 要复杂得多。

标签: java generics inheritance


【解决方案1】:

都没有。

使用这个:

public class PointCloudReader<P extends Point, T extends PointClound<P>> { 
    T read(String path);
}

这不好,因为它使用 raw 类型的PointCloud,并且无论如何都不起作用:

public class PointCloudReader<T extends PointCloud> { 
    T read(String path);
}

这不好,因为它使用了 unknown 类型的PointCloud,而且无论如何都不起作用:

public class PointCloudReader<T extends PointCloud<?>> {
    T read(String path);
}

【讨论】:

  • Java 无法从超类推断 T 的边界。你必须重述它。应该是class PointCloudReader&lt;T extends Point&gt; extends PointCloud&lt;T&gt; :ideone.com/fNSkyi。我冒昧地更新了它。如果您不同意,请告诉我
  • 谢谢,但你的意思不是:public class PointCloudReader&lt;T extends Point&gt; { PointCloud&lt;T&gt; read(String path); }
  • 我正在使用 JNI,所以泛型给我带来了一些麻烦......
  • 我认为@LouisWasserman 的评论对我有用。
  • @VladAdrianMoglan 我最初自己编写了 Louis 的建议,但简化了它,因为它似乎没有必要,我把它放回去了。
【解决方案2】:

不同之处在于,在第一种情况下,您使用的是不推荐的原始类型。在第二种情况下,您使用的是类型更安全的通配符。

例如,考虑以下代码:

class Test <T extends ArrayList<?>>{
        void test(T t) {
            Object o=t.get(0);
            t.add("someStr"); //this line will be a compile error
        }
    }

如果你使用&lt;T extends ArrayList&gt;,你不会得到任何编译错误,但如果你使用了错误类型的ArrayList,则会在运行时抛出异常。
但是如果你使用&lt;T extends ArrayList&lt;?&gt;,就会出现编译错误警告你这一行不是类型安全的。

【讨论】:

    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2010-10-04
    相关资源
    最近更新 更多