博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
五分钟学会java中的基础类型封装类
阅读量:4035 次
发布时间:2019-05-24

本文共 4204 字,大约阅读时间需要 14 分钟。

在刚刚学习java的时候,老师不止一次的说过java是一种面向对象的语言,万物皆对象。对于java中的基础数据类型,由于为了符合java中面向对象的特点,同样也有其封装类。这篇文章对其有一个认识。

一、基本认识

其实在jdk1.5之前,在基础数据类型与其封装器之间的转化必须手动进行,但是从jdk1.5之后,由于提供了自动装箱的机制,因此我们不再手动进行了。

装箱:基础类型转封装类型。Integer a = 3

底层实现:Integer a = Integer.valueOf(3);

拆箱:封装类型转基础类型。int b = a;

底层实现:int b = a.intValue();

既然封装类能够封装基础类型,那么能封装的范围是多少呢?

基本类型 封装器 字节数 最大值 最小值
byte Byte 1byte 2^7 - 1 -2^7
short Short 2byte 2^15 - 1 -2^15
char Character 2byte 2^16 - 1 0
int Integer 4byte 2^31 - 1 -2^31
long Long 8byte 2^63 - 1 -2^63
float Float 4byte 3.4e+38 1.4e-45
double Double 8byte 1.8e+308 4.9e-324
boolean Boolean 1byte/4byte/不明确 - -

我们对其进行了一个总结。不过我们应该注意到boolean类型没有给出精确的定义,可能是一个字节也有可能是四个字节,这是为什么呢?java虚拟机规范中规定的是4个字节,但是不同的厂家虚拟机可能不同,所以可能不会按照规范来。

以上这张图想必我们都不陌生,每一种基础类型都有一个唯一的封装类。而且也给出了字节数、最大值最小值等。下面我们就看一下其基本使用:

public class Test{
public static void main(String[] args) {
Integer int_a= new Integer(3); int int_b= int_a;//自动完成了拆箱 char char_a = new Character('a'); char char_b = char_a;//自动完成了拆箱 //其他类似 }}

二、基础类型与封装类的区别

1、传递方式不同

基本类型是按值传递,而封装类型是按引用传递的。int是基本类型,直接存放数值;Integer类会产生一个对象引用指向这个对象。

2、存储位置不同

基本类型存储在栈中,封装类的引用存储在栈中,而值是存在堆中。这样看上去好像基础封装类多此一举,而且基本类型的速度也确实会比封装类更快。为什么快呢?这是因为封装类涉及到了对象内存的分配和垃圾回收。但是基本类型直接拿起来就计算了。

三、源码分析

在讲解源码之前我们先给出一个神奇的例子,请看下面的代码:

public class Test{
public static void main(String[] args) {
//这种情况会返回true Integer a1 = 10; Integer a2 = 10; System.out.println(a1 == a2); //这种情况会返回false????? Integer b1 = 1000; Integer b2 = 1000; System.out.println(b1 == b2); }}

第一种情况感觉和第二种情况一模一样呀,为什么第二种是false呢?想要知道原因,我们就必须要深入到源码中找寻答案。

public static Integer valueOf(int i) {
// i是否在表示范围[-128, 127]中 if (i >= IntegerCache.low && i <= IntegerCache.high) // 如果在直接取出 return IntegerCache.cache[i + (-IntegerCache.low)]; // 如果不在,则创建一个新的 return new Integer(i);}

也就是说,在合理表示范围之内就直接拿出来一个旧的数据,如果不在表示范围之内那就创建一个新的。但是对于源码的了解不能仅限于此。我们还是按部就班的分析,下面我们以Integer封装类为例。

1、参数

//最小值::-2147483648//其实也就是2的10次方,然后取负@Native public static final int   MIN_VALUE = 0x80000000;//最大值//其实也就是2的10次方@Native public static final int   MAX_VALUE = 0x7fffffff;

2、方法

//方法1:将字符串参数解析为有符号的整数//第二个参数指定基数public static int parseInt(String s, int radix) ;//方法2:类型转换,并给出其中一个例子public byte byteValue(){
return (byte) value;}public short shortValue()public int intValue()public long longValue()public float floatValue()public double doubleValue() //方法3:求a和b的和public static int sum(int a, int b)//方法4:求最大最小值public static int max(int a, int b){
return Math.max(a, b);}public static int min(int a, int b){
return Math.min(a, b);}

3、缓存

上面支持给出了一些基本的使用方法,不过最核心的还是缓存范围的实现。下面我们看一下:

private static class IntegerCache {
static final int low = -128; static final int high; static final Integer cache[]; static {
int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) {
} } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); assert IntegerCache.high >= 127; } private IntegerCache() {
} }

上面这些代码能看懂最好,看不懂我来描述一下大概意思:这是一个静态内部类,类中定义一个静态cache数组,这个静态数组预先放了自己指定范围内的数据,拆箱的时候首先判断范围然后从缓存数组中去抓取数据。就是这么一个简单的过程。

四、使用场景

上面分析了这么多,最主要的还是如何使用,在什么地方使用。下面我们就总结几个场景:

1、类型之间的转换:

String b = "123"; int c = Integer.parseInt(b); //如果b中含有非法字符,则会报错NumberFormatException

2、泛型中使用

List<>为原始类型,不指定元素类型时,会出现不安全的警告:

List is a raw type. References to generic type List should be parameterized

大概意思就是:List的<>中应该指定清楚是那种类型,如Integer、String等。

3、强制类型转换

4、集合中使用

public static void main(String[] args) {
List
list = new ArrayList
(2); list.add(1); list.add(null); for (int value:list){
System.out.println("value:"+value); }}

这种情况下会出现空指针异常。

OK。今天的文章先到这里,如有问题还请批评指正。

在这里插入图片描述

转载地址:http://pnbdi.baihongyu.com/

你可能感兴趣的文章
ArrayList集合解析
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
Android计算器实现源码分析
查看>>
Android系统构架
查看>>
Android 跨应用程序访问窗口知识点总结
查看>>
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
js弹窗插件
查看>>
自定义 select 下拉框 多选插件
查看>>
js判断数组内是否有重复值
查看>>
js获取url链接携带的参数值
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>
arm linux 生成火焰图
查看>>
linux和windows内存布局验证
查看>>
linux config
查看>>
linux insmod error -1 required key invalid
查看>>
linux kconfig配置
查看>>
linux不同模块completion通信
查看>>
linux printf获得时间戳
查看>>