当前位置: 首页 > 知识库问答 >
问题:

Java泛型与不兼容类型:编译器中的bug?

年烈
2023-03-14

在stackoverflow中还没有讨论的情况下,我遇到了“不兼容类型”编译器错误(例如,为什么这个通用java代码不能编译?)。

我的期望很简单--我调用的是一个模板化方法,它不使用包含类的任何“泛型”类,因此它应该从方法参数中提取模板参数的类型,并且在所有情况下都应该编译--但我得到了“不兼容类型”编译器错误。

我注意到解决这个问题的奇怪方法--在方法参数中向泛型datatype添加“<?extends Data>”。它如何改变编译器逻辑?

public void processData(DataContainer<? extends Data> c) {
DummyContextClass dcc = (DummyContextClass)c.getContext(DummyContextClass.class);

复制/粘贴代码

public class Test {

    public static class Data {
    }

    public static class DataContainer<TData extends Data> {
        public final TData Data;
        private final Map<String, Object> contexts = new HashMap<>();

        public DataContainer(TData data) {
            Data = data;
        }

        public <T> T getContext(Class<T> type) {
            return (T)contexts.get(type.getName());
        }

        public <T> void setContext(Class<T> type, T context) {
            contexts.put(type.getName(), context);
        }
    }

    public static class DummyContextClass {
    }

    public void processData(DataContainer c) {
        c.setContext(DummyContextClass.class, new DummyContextClass());

        // error: incompatible types: Object cannot be converted to DummyContextClass
        DummyContextClass dcc = c.getContext(DummyContextClass.class);
    }
}

共有1个答案

茹展鹏
2023-03-14

问题与泛型方法无关。
问题是使用原始类型作为方法的参数:

public void processData(DataContainer c) { // Oops! DataContainer is a raw type

您应该在DataContainer中使用参数:

public void processData(DataContainer<? extends Data> c) {

当您删除泛型类的类型时,您就拥有了所谓的原始类型,并且(由于与旧java版本的兼容性要求),所有泛型信息都将从类中剥离出来。它(除其他外)将声明为泛型类型的所有返回类型更改为object,因此出于编译目的,您的方法现在看起来如下所示:

public Object getContext(Class type) {
 类似资料:
  • 问题内容: 我在写一些代码,遇到编译错误。这就是我所拥有的: 我以为使用继承时没有正确声明泛型,所以我检查了Oracle的教程,他们在其中编写 上面的声明使用相同的泛型类型,这是我在示例中要完成的工作。似乎假设from 与from 有所不同。否则,它应该能够 将 两者 合并并看到相同的类型。如何正确实现我要实现的目标? ( 即,某物的常量是某物的值,这是同一物的表达 ) 问题答案: 您的变量定义为

  • 我定义jackoson序列化器并将其添加到java类中,如下所示: 编译器出现以下错误: 注释的定义为: 如果我从ReportFilterDeserializer中删除泛型attibute,它将通过编译。我不明白编辑为什么抱怨。

  • 在下面的情况下,我在理解Java泛型的行为时遇到了问题。 具有一些参数化接口和一些类上的方法,这些类返回扩展该接口的类,由、1.8Oracle JDK、OSX和Linux生成java编译错误,但不是由Eclipse IDE中的Eclipse编译器生成的(它也可以在Eclipse RCP OSGi运行时下运行),实现如下: ./Gradlew build 最简单的修复是删除方法签名中泛型定义的一部分

  • 我是一名java初学者,我正在阅读“Java初学者指南”这本书和泛型的主题。作者创建了以下泛型类: 在这种情况下,类型参数必须是Number或Number的子类。 作者说,如果我们添加一个新方法来检查存储在两个通用对象中的数值绝对值,如下所示: 用它写的解释是: 这里,使用标准方法Math.abs()获取每个数字的绝对值,然后进行数值比较,这种尝试的麻烦在于,它只会对类型与调用对象相同的其他Num

  • 在处理一些旧代码时,我偶然发现了一个问题,用lambda表达式或方法引用替换了几个匿名类。这个问题有点难以用语言来解释,但我会尽我所能,下面我还添加了一个简短的例子,尽我所能来说明我的问题。 我的示例包括。。。 > 一个函数接口,GenericListener,它接受类型参数V并具有单个方法“GenericCallback(V GenericValue)”。 一个类,CallbackProduce

  • 和是的一部分,如下所示: