这篇文章主要介绍了Java中泛型和包装类的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。我们之前实现过的顺序表,实现的是保存某一类型的元素(如 int
型)示例代码:但是这样写的话,这个顺序表就只能存储 int
类型的元素了如果现在需要保存指向 Person
类型对象的引用的顺序表,该如何解决呢?如果又需要保存指向 Book
类型对象的引用呢?首先,我们在学习多态的时了解到:基类的引用可以指向子类的对象其次,我们也知道 Object
类是 Java 中所有所有类的祖先类因此,要解决上述问题,我们可以这样做将我们的顺序表的元素类型定义成 Object
类型,这样我们的 Object
类型的引用可以指向 Person
类型的对象或者指向 Book
类型的对象示例代码:这样,我们就可以很自由的存储指向任意类型的对象的引用到我们的顺序表了示例代码:遗留问题: 现在的 MyArrayList
虽然可以做到添加任意类型的引用到其中,但会遇到下面的问题当我们使用这样的代码时,明知道存储的是哪种类型的元素,但还是要进行强制转换。如虽然知道返回的元素是 int 类型,但还是要进行强制类型转换创建的一个 MyArrayList
中可以存放各种类型,形成了一个大杂烩。并且将 Object 类型(具体是 A 类型)转换为 B 类型时,即使强制转换,也会产生异常 ClassCastException
因此 Java 针对这一问题就出现了泛型Java 泛型(generics)是 JDK 5 中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型可以分为两类泛型类泛型方法预备知识主要是为了学习、理解集合框架,所以这里只简单介绍泛型类,后面将会专门为泛型写一个章节。规则:在类名后面添加了类型参数声明泛型类的类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符泛型的泛型参数一定是类类型,如果是简单类型,那么必须是对应的包装类这里直接将上面定义的 MyArrayList
类改写成泛型类示例代码:此时我们就将这个顺序表改写成了一个泛型类,接下来我们来使用它示例代码:上述的 myArrayList
只能存放 String
类型的元素,并且不需要再添加强制类型转换泛型的意义:自动进行类型的检查自动进行类型的转换Java 中泛型标记符: 类型形参一般使用一个大写字母表示,如:E — Element(在集合中使用,因为集合中存放的是元素)T — Type(Java 类)K — Key(键)V — Value(值)N — Number(数值类型)? —表示不确定的 Java 类型如果不重写 toString
方法,输出某个类的实例化对象,如代码示例:结果为:如果用上述的泛型类,输出其实例化对象,如代码示例:结果为:我们发现:泛型类和非泛型类输出的样例格式都是一样的:类名@地址
为什么泛型类的实例化对象结果不是输出泛型类后面的泛型参数 呢?这里就要了解泛型是怎么编译的泛型的编译使用了一种机制:擦除机制擦除机制只作用于编译期间,换句话说,泛型就是编译时期的一种机制,运行期间没有泛型的概念解释:当我们存放元素的时候,泛型就会根据
自动进行类型的检查。但编译的时候,这些
就被擦除成了 Object
Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要失效了?实际上也确实如此,为了解决这个问题,Java 中引入了一类特殊的类,即这 8 种基本数据类型的包装类。在使用过程中,会将类似 int 这样的值包装到一个对象中去。Java 是一个面向对象的语言,基本类型并不具有对象的性质,为了与其他对象“接轨”就出现了包装类型既然包装类是一个类,那么就有它对应的成员变量和成员方法。打孔大家可以具体的去查看文档了解各个包装类包装类中有两个重要的知识点,装箱和拆箱装箱: 把基本数据类型转为对应的包装类型拆箱: 把包装类型转换为基本数据类型装箱示例代码:拆箱示例代码:那自动装箱又是什么呢?我们可以对下面这份代码进行反编译(反编译指令为 javap -c 类名
)代码示例:通过反编译指令,得到了如下结果:我们发现在底层中 10 是通过 Integer.valueOf
这个静态方法赋值给了 i,进行装箱操作再将 i 通过 Integer.intValue
这个方法复制给了 j,进行拆箱操作那么什么是手动装箱和手动拆箱呢?就是和底层原理一样,通过 Integer.valueOf
和 Integer.intValue
方法进行的装箱和拆箱就是手动的而不是通过这些方法进行的装箱和拆箱就是自动的思考下列代码结果:结果为:true再看一个代码:结果为:false这是为什么呢?首先我们看到 a 和 b 都进行了装包操作,因此我们就要去了解装包的时候发生了什么通过转到 Integer.valueOf
的定义我们看到该定义意思就是:如果 i 大于等于 Inte免费云主机域名gerCache
的最小值,小于它的最大值,就返回 IntegerCache.cache[i + (-IntegerCache.low)]
,否则就返回 new Integer(i)
而 new 一个对象的话,相当于比较的就是地址的值了,所以是 false因此我们要知道 IntegerCache
的最大值以及最小值是多少,此时我们转到它的定义上图中我们了解到 low 为 -128、high为 127,而 cache 其实就是一个数组。我们知道数组的下标是从 0 开始的,而 i + (-IntegerCache.low)
表示的最小值正好就是 0,也就是说明数组下标为 0 时存储的值就为 -128,并且依次往后递推。因此数值在 -128 到 127 之间时返回的就是和这个数相同的值,所以结果为 true那为什么要专门创建一个数组呢?所有数字返回 new 的对象不就行了吗?这是因为,这样做可以提高效率。实例化对象是需要消耗资源的。而数组其实就是一个对象,可以减少资源的消耗。感谢你能够认真阅读完这篇文章,希望小编分享的“Java中泛型和包装类的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持百云主机,关注百云主机行业资讯频道,更多相关知识等着你来学习!
这篇“如何解决PHP高并发问题”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何解决PHP高并发问题”文章吧。秒杀会产生一个瞬间的高并发,使用数…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。