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

通用螺丝非相关集合

王云
2023-03-14

为什么与模板类不相关的集合会删除其类型?下面是一个例子:(很抱歉,由于我对错误感到困惑,它将无法编译。)

package test;

import java.util.ArrayList;
import java.util.List;

public class TemplateTest {

    public static class A { }

    public static class B<T extends Comparable> {
        List<A> aList = new ArrayList<A>();

        public List<A> getAList() {
            return aList;
        }

        public int compare(T t, T t1) {
            return t.compareTo(t1);
        }
    }

    public static void main(String[] args) {
        B b = new B();
        for (A a : b.getAList()) { //THIS DOES NOT WORK

        }
        List<A> aList = b.getAList(); //THIS WORKS
        for (A a : aList) {

        }
    }
}

此代码在编译时引发错误:

test/TemplateTest.java:24: incompatible types
    found   : java.lang.Object
    required: test.TemplateTest.A
        for (A a : b.getAList()) {

如果我指定BlikeB的模板

怎么回事啊?

编辑:人们指出没有必要将B设置为通用的,所以我将其添加到了B中


共有3个答案

阮飞翔
2023-03-14

这真的很像这个bug:

6760983:不相关方法中未使用的类型参数触发错误

据报道:

未使用的泛型导致问题

江光明
2023-03-14

首先,在Java中,它是泛型,而不是像C中那样的模板。

您正在类B中声明泛型类型参数T,但未使用它。在整个B类定义中,您应该使用T而不是A

public static class B<T> {
    List<T> aList = new ArrayList<T>();

    public List<T> getAList() {
        return aList;
    }
}

然后,当您声明类B的实例时,您应该使用类型参数。

B<A> b = new B<A>();

但是如果您知道您的aList变量总是像方法名getAList所建议的那样保存A类型的对象,那么就没有理由将类B设为泛型。

阎辰钊
2023-03-14

是的,已知的行为是,如果您使用原始类型,那么类上的所有类型参数都会丢失,而不仅仅是您未能声明的类型级参数。

部分原因在于:

如果我指定B的模板,比如B

这不是一个选项,您不能选择是否要指定类型参数。它编译时没有指定参数的唯一原因是为了向后兼容。编写缺少类型参数的新代码是一个编程错误。

列表

for(A:b.getList()) {}将该警告升级为错误,因为插入的强制转换将在编译器生成的代码中,因此它根本拒绝自动生成不安全的代码,而不仅仅是发出警告。

从java语言规范:

仅允许使用原始类型作为对遗留代码兼容性的让步。在将泛型引入Java编程语言后编写的代码中使用原始类型是非常不鼓励的。Java编程语言的未来版本可能不允许使用原始类型。

事实上,java泛型与C模板共享的唯一重要内容是

更多细节:什么是原始类型,为什么我们不应该使用它?

 类似资料:
  • 概述 半圆头螺丝是一种新型的螺丝,它具有较小的头部,可以解决大多数螺丝头干扰其他部件的问题。 该螺丝需要使用HEX螺丝刀2.5mm进行紧固。 参数 材质:不锈钢 半圆头螺丝M4x8 半圆头螺丝M4x14 半圆头螺丝M4x16 半圆头螺丝M4x22 半圆头螺丝M4x30 半圆头螺丝M4x35 半圆头螺丝M4x40

  • Open-Falcon数据收集,分为[绘图数据]收集和[报警数据]收集。下面介绍,如何验证两个链路的数据收集是否正常。 如何验证[绘图数据]收集是否正常 数据链路是:agent->transfer->graph->query->dashboard。graph有一个http接口可以验证agent->transfer->graph这条链路,比如graph的http端口是6071,可以这么访问验证: #

  • 对于我正在构建的应用程序,我需要能够发送slack消息,指示处理文件的进度和成功/失败。 我没有找到一种完全直接的方法,所以我做了以下几点: 声明队列通道以接收需要发送的消息 发送到该通道的每条消息都将作为松弛消息发送。为了在那里推送信息,我做了一个窃听,比如: 最后,松弛流: 类SlackService具有发送消息的所有逻辑。我喜欢这种方法,因为我可以从不同的地方向slack通道发送消息,并以相

  • Open-Falcon数据收集,分为[绘图数据]收集和[报警数据]收集。下面介绍,如何验证两个链路的数据收集是否正常。 如何验证[绘图数据]收集是否正常 数据链路是:agent->transfer->graph->query->dashboard。graph有一个http接口可以验证agent->transfer->graph这条链路,比如graph的http端口是6071,可以这么访问验证: #

  • 本文向大家介绍非常漂亮的相册集 使用jquery制作相册集,包括了非常漂亮的相册集 使用jquery制作相册集的使用技巧和注意事项,需要的朋友参考一下 一、简单的图像翻滚 image-rollover常被用在交互式导航栏上,当我们的鼠标移动到导航栏时,按钮的外观改变。例如我们以如下几幅黑白缩略图作为导航图表,当鼠标移动到指定图标时,图标变为明亮的彩色图片。预览如下: 该页面的代码十分简单,我们以此

  •  当玩家点选菜单上的「系统 - 返回之前」后,可以返回上一个段落,通过记录就是指定这种自动存储位置的功能。  要使用通过记录功能,需要用到 record 指令、此外还要对 Config.tjs 的 recordHistoryOfStore 进行设定。  「系统 - 返回之前」这一菜单选项默认是不显示的,但是可以在 Config.tjs 中将 goBackMenuItem.visible 设定为 t