Java 深入理解泛型的强制转型及自动转型

java之强转泛型遇到的坑 最近小博主再学习泛型中遇到了一些坑,再这里把这个坑跟大家说下,让大家少走弯路 直接上图 (A[])new Object[newCapacity) 这句虽然在编译器中没有语法上的错误,可是一运行则爆出下面这样的错误 一开始,复查了十几遍也以为是自己泛型定义错了,甚至也重写了好几次方法,最重点的是即使debug编译器还没走到方法里面就报错。但是不负有心人,经过了一天的排查,原来是Object类型... 阅读详情

前言:Java的泛型真是狗屎!

一、泛型里的强制转换

在阅读 Core Java 和 ArrayList 源码时,一直有一个问题困扰着我:既然泛型都会被擦出成raw type(这里被擦除为Object),那么为什么还会有(T) 或(T[ ])这种强制转换呢?这岂不是闲的没事儿干?

public class Test<E> {
    private Object[] elem;
    public E get(int index) {return (E)elem[index];}  // ????????????黑人问号脸
    public void set(int index, T e) {elem[index] = e;} 
}

如果对泛型理解不深刻的小伙伴一定会觉得去掉(E[ ])强制转换也是可以的。如果你自己试一下的话,相信一定会有一个大大的编译错误等着你。

为什么呢?永远要记住,Java的弱鸡泛型是编译期技术,换句话说也就是Java的泛型只存在于你在eclipse/IDEA按下运行按钮的那一刻之前。在编译期,并没有类型擦除,所以在编译器看来你自己定义的类型T是真实存在的类,和String、Integer等类没有区别。所以你必须对Object[ ]加入强制转换。但这会又会出现一个“unchecked”警告(Java泛型真是狗屎x2)。可以在代码中加入@SuppressWarning("unchecked")来抑制住这个警告(Java泛型真是狗屎x3)。

二、泛型里的自动转换

既然泛型会被擦除成 raw type ,所以他肯定还会转换成你要赋给的 那个变量的类型。咋转换的?自动的。啥时候转换的?直接看字节码,来个透彻的。

Java代码:

import java.util.ArrayList;

public class Test<T>{
	
	private T obj;	
	public void set(T obj) {this.obj = obj;}	
	public T get() {return this.obj;}	
	
	public static void main(String[] args) {		
		Test<String> t = new Test<>();
		t.set("xixixi~");
		String str = t.get();
		System.out.println(str);	
	}	
	
}

字节码:

 0 new #1 <Test>
 3 dup
 4 invokespecial #30 <Test/<init>()V>
 7 astore_1
 8 aload_1
 9 ldc #31 <xixixi~>
11 invokevirtual #33 <Test/set(Ljava/lang/Object;)V>
14 aload_1
15 invokevirtual #35 <Test/get()Ljava/lang/Object;>
18 checkcast #37 <java/lang/String>       //注意这一行!!!
21 astore_2
22 getstatic #39 <java/lang/System/out Ljava/io/PrintStream;>
25 aload_2
26 invokevirtual #45 <java/io/PrintStream/println(Ljava/lang/String;)V>
29 return

注意字节码编号为18的这一行!checkcast指令为检测是否可以转换成String并执行转换。为啥可以转换?你传的时候就是一个String当然可以转换了!只不过擦除就相当于对你传入的String进行了一次向上转型到Object,现在再自己向下转型回来。所以说,Java的泛型是一项安全技术,在编译期检测你的类型不让你随意乱传递参数。

但是千万不要头脑发热进行像下面的一样的操作:

import java.util.ArrayList;

public class Test{
	
	public static <T extends Integer> T[] getArray() {
		Object[] objArr = new Object[20];
		return (T[])objArr;		
	}
	
	public static void main(String[] args) {
		Integer[] intArr = Test.getArray();
	}	
}

如果运行你必定会报一个类型转换异常。为啥?这里的Object[ ]是直接创建,并不是经过擦除(向上转型)得来,所以泛型中对Object[ ]的应用只能用在类私有域(在取值时强转,见最开始的代码),因为其无法转换成其他类型的数组。关于泛型方法如何返回数组,请详见Core Java P324页,这里不再赘述。

Java 泛型是什么?一文带你吃透泛型 它是一个泛型类,而我之前使用的时候并没有传递,说明 Java 语法是允许的,这个时候传递的类型是 Object 类,虽然它是所有类的父类,可以存储任意的类型,但是在遍历、获取元素时需要原来的类型就要进行强制转换。泛型接口有两使用方式,要么在实现接口时确定泛型类的类型,要么在实现接口时先不确定泛型类类型,而在实例化对象时再确定。这个时候就会出现一些问题,假如往链表里存储了许多不同类型的数据,在强转的时候就要判断每一个原来的类型,这样就很容易出现错误。,泛型在类中可以创建变量,也可以作为方法的参数或者返回值。 阅读详情

相关推荐

2.6 SST的核心性能指标体系

本文构建了固态变压器(SST)的核心性能指标体系,涵盖电气性能、可靠性、经济性和环境适配性四大类指标。电气性能指标包括运行效率(≥97%)、功率密度(≥900kVA/m³)、谐波畸变率(≤3%)等关键参数;可靠性指标设定MTBF≥43800h、年均故障率≤1.2次/年等标准;经济性指标对比分析了初始购置成本(45-55万元)和全生命周期成本(48-55万元);环境适配性指标则明确了温度、海拔等工况要求。该体系采用量化公式和国标限值,为SST的性能测试、选型和优化提供了统一标准。

技术工作者 602

java基础进阶六-泛型

泛型,可以看做一种“模板代码”。 什么是“模板代码”呢? 以ArrayList为例。 在JDK1.5引入泛型之前,ArrayList采取的方式是:在内部塞入一个Object[] array。 public class ArrayList { private Object[] array; private int size; public void add(Object e) {...} public void remove(int index) {...} publi

qq_45891099的博客 1864

重带电粒子的能量歧离(energy straggling)

能量歧离,Bethe-Bloch

G751888629的博客 2298

Java泛型

一、概述 1.1、什么是泛型?为什么要使用泛型?类型擦除? 什么是泛型? ​ 泛型:参数化类型 ​ 对于参数,通常情况下,我们理解为 方法有形参,然后调用方法的时候传递实参。 ​ 而参数化类型是把类型由原来的具体的类型参数化(参数化是个动词)。即把类型当做是参数一样传递。 为什么要使用泛型? ​ 在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

想要腹肌的熊的博客 2871

Windows非分页缓冲池内存泄漏实战:PoolMon与RAMMap高效排查指南

本文详细介绍了Windows系统中非分页缓冲池内存泄漏的实战排查方法。当系统出现卡顿且内存占用异常增长时,通过RAMMap工具快速定位非分页缓冲池异常,并利用PoolMon监控内核内存分配标签,精准锁定泄漏源。文章提供了从确认症状、安装工具到使用findstr命令溯源驱动文件的完整五步排查流程,并总结了常见泄漏标签与解决方案,帮助用户高效解决深层系统内存问题。

weixin_28455801的博客 1011

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

WW、forever的博客 2158

Java中优雅实现泛型类型的强制转换

Java中优雅实现泛型类型的强制转换

byx的博客 3172

Python 爬虫实战:拼多多商品评论情感分析(含词云生成与差评预警)

在电商行业竞争日益激烈的当下,商家对商品评论的分析需求愈发迫切。通过 Python 爬虫收集拼多多商品评论,并结合情感分析、词云可视化及差评预警技术,商家可精准洞察消费者反馈,优化商品与服务。本文将深度剖析从爬虫搭建到数据挖掘的关键环节,助力读者构建全流程电商评论分析系统。

yansideyucsdn的博客 1450

java强制转换概念_Java的“泛型”特性,你以为自己会了?(万字长文)

使用Java的小伙伴,对于Java的一些高级特性一定再熟悉不过了,例如集合、反射、泛型、注解等等,这些可以说我们在平时开发中是经常使用到的,尤其是集合,基本是只要写代码没有用不到的,今天我们先来谈谈泛型。1. 定义在了解一个事物之前,我们必定要先知道他的定义,所以我们就从定义开始,去一步一步揭开泛型的神秘面纱。# 泛型(generics) 他是 JDK5 中引入的一个新特性,泛型提供了编译时类型安...

weixin_30000523的博客 704

流体仿真软件:COMSOL Multiphysics二次开发_(11).COMSOL与外部软件的数据交换

通过上述方法,您可以实现 COMSOL Multiphysics 与外部软件的数据交换,从而更好地集成和分析仿真结果。无论是从文本文件导入数据,导出数据到 MATLAB,还是通过 API 和 COMSOL Server 实现实时通信,都能满足不同场景下的需求。希望这些内容对您在流体仿真领域的开发工作有所帮助。

kkchenjj的博客 1553

AD9361功能介绍和使用

AD9361使用分数分频锁相环(PLL)来产生发射机和接收机本地振荡器(LO)频率和BB PLL。BB PLL 可用于数据转换、数字滤波器和 |/O 端口。PLL的参考时钟可以由外部振荡器或外部晶体(XO)和数字可编程片内可变电容提供,电容微调产生参考时钟频率,XO和微调电容的组合统称为DCXO。有多个天线输入的分集系统。接收链数据首先经过低噪声放大器(LNA),然后是同相(1)和正交(Q)放大器,混频器和频带整形滤波器,可将接收到的信号下变频为基带以进行数字化。时分双工(TDD)和频分双工(FDD)。。。

wangjie36的博客 1万+

【Java基础】泛型相关知识点总结

泛型,其实算是Java当中经常使用且比较难的语法了,很多人一开始都很难理解,下面,我将会用简单的方式带你去理解它,让你打好基础,以后不必再害怕~ Java之泛型泛型的定义为什么要用到泛型三级目录 泛型的定义 这里大家可以不必去看网上的有些定义,因为相对于比较学术化,只需记住泛型可以在程序设计中指定某种类型,让程序的设计更加规范化即可 为什么要用到泛型 了解到了泛型是什么后,那我们来讨论讨论为什么要用泛型这个语法,这个语法到底是干什么的?别急,下面,我先给大家举一个例子: class Stack { .

沐北的博客 2168

人体红外传感器HC-SR501

本文记录的是如何用stm32使用HC-SR501。实验平台:野火指南者stm32f103vet6。实验现象:一旦有人体经过,LED会亮红色。HC-SR501 传感器工作原理人体都有恒定的体温,一般在 37 度,所以会发出特定波长 10UM 左右的红外线,被动式红外探头就是靠探测人体发射的 10um 左右的红外,进行工作的。人体发射的 10um 左右。

weixin_43772611的博客 1万+

Java泛型深入理解

Java泛型,包括Java泛型的实现,泛型擦除以及相关面试题,通配符理解

void 10万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java泛型的深入理解以及上下限泛型和泛型通配符

详细介绍了Java中的泛型的概念、原理和使用,比如上、下限泛型、泛型通配符等。

终生学习践行者 2661

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

深入理解java的泛型

文章目录简介泛型和协变泛型在使用中会遇到的问题类型擦除要注意的事项总结 深入理解java的泛型 简介 泛型是JDK 5引入的概念,泛型的引入主要是为了保证java中类型的安全性,有点像C++中的模板。 但是Java为了保证向下兼容性,它的泛型全部都是在编译期间实现的。编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。这种就叫做类型擦除。编译器在编译的过程中执行类型检查来保证类型安全,但是...

程序那些事 9600

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java 泛型:深入理解泛型的类型擦除

泛型代码和虚拟机 Java 中的的泛型是伪泛型,为什这么说呢?因为 Java 在编译期间,所有的泛型信息都被擦除掉。称为类型擦除(type erasure) 在 Java 虚拟机中没有泛型类型对象 – 所有对象都是属于普通类 , 所以我们要了解一下 类型擦除 的概念。 1. 类型擦除 无论何时定义一个泛型类型,都会自动提供一个响应的 原始类型 (raw type)(不存在泛型 )。原始类型的名字...

Strange_Monkey的博客 3165

泛型是什么?

泛型,一个所有人都知道怎么用,在JAVA世界老生常谈的特性。更需要知其然,知其所以然。

Steins Gate 1万+

深入理解java泛型

为什么需要泛型? 泛型是java SE1.5的新特性,泛型的本质是参数化类型,这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。在JavaSE1.5之前没有泛型的情况下只能通过对类型 Object的引用来实现参数的任意化,其带来的缺点是要做显式强制类型转换,而这种转化编译器是不做检查的,容易把问题留在运行时,所以泛型的好处是在编译时检查类型安全,并且所有的强制类型转...

weixin_42759988的博客 2585

深入理解 Java 泛型

首先提个问题: Java 泛型的作用是什么?泛型擦除是什么?泛型一般用在什么场景? 如果这个问题你答不上来,那这篇文章可能就对你有些价值。 读完本文你将了解到: 什么是泛型 为什么引入泛型 泛型的使用方式 泛型类 泛型接口 泛型方法 泛型的通配符 无限制通配符 上界通配符 extends E 下界通配符 super E 通配符比较 泛型的类型擦除 擦除的实现原理 擦除导致

张拭心的博客 shixinzhang 2万+

一文带你深入理解【Java基础】· 泛型

目录写在前面1. 为什么要有泛型1.1 为什么要有泛型1.2 泛型的概念1.3 在集合中使用泛型1.4 泛型代码演示 2. 自定义泛型结构2.1 泛型结构2.2 泛型类、泛型接口2.3 泛型方法2.4 自定义泛型类型代码演示2.5 泛型在继承上的体现3. 通配符的使用3.1 使用通配符3.2 注意点3.3 有限制的通配符3.4 通配符代码演示4. 泛型应用举例4.1 泛型嵌套4.2 实际案例结语【往期回顾】

麟-小白的博客 972

JAVA泛型的使用和深入理解

对泛型进行详细解析,从浅入深,包括为什么需要泛型,泛型怎么使用,泛型有哪些坑,泛型在Gson中的应用

zjm807778317的博客 1278

Java基础泛型

目录:前言一.泛型的理解和好处1.泛型的理解(1) 使用传统方法的问题分析(2) 使用泛型方式2.泛型的好处二.泛型介绍1.什么是泛型2.泛型的语法3.泛型使用细节三.自定义泛型1.自定义泛型类2.自定义泛型接口3.自定义泛型方法四.通配符1.泛型继承性2.通配符 前言 最近在回顾JavaSE部分的知识,对一些薄弱的知识进行记录,学习方式,通过视频和图书的进行学习,视频看B站韩顺平老师的30天学会Java,图书看Java核心技术 卷I 基础知识(原书第10版)。 韩顺平30天学会地址:Javahttps

孤夜的博客 1802

深入理解什么Java泛型?

文章目录Java泛型什么是泛型?泛型类与接口泛型类泛型派生子类泛型接口泛型方法可变泛型方法类型通配符类型通配符上限类型通配符下限有限制类型擦除方法中类型定义的参数擦除桥接擦除泛型数组方式一:可以申明带泛型数组的引用,不能直接创建带泛型数组的对象方式二:采用java.lang.reflect.Array.newInstance(Class<?> componentType, int length)泛型与反射} } 运行结果: 下标为2的元素:柠檬 Java泛型 什么是泛型? 泛型是jdk1

逆空_35208312的博客 594
上一篇: JVM 类文件结构
下一篇: C语言多维数组与指针的关系
donCoder
博客等级 码龄9年 65粉丝 79原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值