objList=strList为什么报错

2023-09-14 16:04:04

代码复现

先看下面一段代码

List<String> strList = new ArrayList<>();
List<Object> objList = strList;  // 报错

乍一看好像没什么问题,但为什么追报错呢?

先别急,看下面一段代码

List<Integer> intList = new ArrayList<>();
List<Object> objList = intList;
objList.add("hello");  // 添加某个未知类型
Integer i = intList.get(0);  // 结果一定是Integer吗

偷偷把str放到objList里了,但又从intList拿出来了?

看来你应该知道编译器为什么报错了吧,就是为了防止小白偷偷添加一些奇怪的东西

如何防止

简单啊,只要禁止add()就行了

List<Integer> intList = new ArrayList<>();
List<? super Integer> objList = intList;
objList.add("hello");  // 报错
Integer i = intList.get(0); 

我们通过**? super Intege**限定了List的下界,此时objList只能存入某个Integer的父类以及父类的子类。但我们只能推断出Integer是该父类的一个子类,所以放入String会报错(String是Object的子类,但不一定是Integer某个父类的子类)。

所以编译器报错是为了防止我们乱添加?

太麻烦了?

// 定义一个接口,里面只有get()
interface MyList<T> {
    T get();
}
// 实例
MyList<String> strList = () -> null;
MyList<Object> objList = strList;  // 拨错
MyList<? extends String> objList2 = strList;  // 正常

编译器报错是为了防止我们乱添加,但MyList接口里没有add()之类的添加方法,也要为了不报错而改成**? extends String**,???

Kotlin的优化

// 接口只有get()方法
interface MyList<out T> {
    fun get(): T
}

val strList: MyList<String> = object : MyList<String> {
    override fun get(): String {
        return "Hello"
    }
}
val objList: MyList<Any> = strList  // 正常

kotlin在语法方面做出的优化,当我们确定不会出现**偷偷把str放到objList里了,但又从intList拿出来了?**这种情况时,可以使用out关键字标记为只读不写

更多推荐

5.14 Set Feature Command

5.14SetFeatureCommandSetFeatureCommand规定了Feature的属性。SetFeatureCommand使用datapointer,CommandDword10,CommandDword11,CommandDword12,CommandDword13,CommandDword14和Co

B : DS顺序表--连续操作

Description建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)该类具有以下成员函数:构造函数:实现顺序表的初始化。插入多个数据的multiinsert(inti,intn,intitem[])函数,实现在第i个位置,连续插入来自数组item的n个数据,即从位置i开始插入多个数据。删除多个数据

vue3+element项目创建

一、创建vue3项目步骤要创建一个Vue3+ElementUI的项目,你可以按照以下步骤进行操作:1.确保你已经安装了Node.js和npm(Node.js的包管理器)。你可以在命令行中运行以下命令来检查它们是否已经安装:node-vnpm-v2.使用VueCLI来创建一个新的Vue项目。在命令行中运行以下命令:npm

一花落,万物生,AIGC为国货复兴注入新活力

在最近的商业新闻中,国货们发“花难财”的热度持续在涨,“花西子”曾经是中国国货的代表之一,以其独特的美妆产品而闻名于世。然而,近期因为李佳琦“79块钱哪里贵了”事件的原因,让不少网友扒出这支79的眉笔算下来一克竟要比黄金还贵,加上主播的出言嘲讽消费者,让大家纷纷开始抵制这个产品。“花西子”翻车之后,国货品牌在一夜之间占

【湖科大教书匠】计算机网络随堂笔记第1章(计算机网络概述)

目录1.1、计算机网络在信息时代的作用我国互联网发展状况1.2、因特网概述1、网络、互连网(互联网)和因特网2、因特网发展的三个阶段因特网服务提供者ISP(InternetServiceProvider)基于ISP的三层结构的因特网3、因特网的标准化工作4、因特网的组成边缘部分核心部分C/S和P2P:客户-服务器方式:

android 逆向去广告工具和流程

主要用到的软件:1、安卓修改大师:有很多功能,但有会员限制。好用的是字符查找后,可以在smali和java切换2、apktool:反编译、回编译工具。但是是命令行方式3、jadx-gui-1.4.7-no-jre-win反编译成java,非常好用4、AndroidKiller_v1.3.1:反编译有些不正常,签名后,在

SpringMVC

目录SpringMVC体系结构SpringMVC配置注解@Controller@RequestMapping@RequestParam@RequestBody@SessionAttributes@DateTimeFormat@ResponseBodySpringMVC体系结构(1)首先浏览器发送请求——>Dispatc

Linux的调试工具 - gdb(超详细)

Linux的调试工具-gdb1.背景2.开始使用指令的使用都用下面这个C语言简单小代码来进行演示:1.list或l行号:显示文件源代码,接着上次的位置往下列,每次列10行。2.list或l函数名:列出某个函数的源代码。3.r或run:运行程序。4.break或b行号:在某一行设置断点5.n或next:单条执行(类似vs

RK3568驱动指南|第五篇 中断-第42章 软中断实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和MaliG522EE图形处理器。RK3568支持4K解码和1080P编码,支持SATA/PCIE/USB3.0外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568支持安卓11和li

快速排序模拟实现

快速排序,时间复杂度为O(NlogN),属于排序中相对快的那一列,以下是快排的模拟实现:法一:左右指针交换法voidswap(int*x,int*y){inttmp=*x;*x=*y;*y=tmp;}//交换函数intgetmid(int*a,intleft,intright){intmid=(left+right)/

【错误记录】IntelliJ IDEA 导出可执行 jar 包执行报错 ( java.lang.ClassNotFoundException | 打包时没有选择依赖库 )

文章目录一、报错信息二、解决方案一三、解决方案二一、报错信息参考【IntelliJIDEA】导出可执行JAR包博客,从IntelliJIDEA中导出可执行JAR包;执行菜单栏/Build/BuildArtifacts选项,编译Module中配置的artifacts项目;编译完成artifacts后,进入到工程目录\ou

热文推荐