博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基本类型与引用类型
阅读量:4987 次
发布时间:2019-06-12

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

目录

java基本类型与引用类型
目录
一基本数据类型
二引用类型
三基本类型与引用类型的区别
默认值
内存分配
自动装箱自动拆箱
自动装箱拆箱带来的问题
程序的性能
空指针异常
对象相等比较时
一、基本数据类型
java中一共分为8种基本数据类型:byte、short、int、long、float、double、char、boolean,其中byte、short、int、long是整型。float、double是浮点型,char是字符型,boolean是布尔型。

二、引用类型

java为每种基本类型都提供了对应的封装类型,分别为:Byte、Short、Integer、Long、Float、Double、Character、Boolean。引用类型是一种对象类型,它的值是指向内存空间的引用,就是地址。

三、基本类型与引用类型的区别

1.默认值
整型byte、short、int、long的默认值都为0,浮点型float、double的默认值为0.0,boolean默认值为false,char默认值为空。对应的包装类型默认值都为null。

2.内存分配

基本数据类型的变量是存储在栈内存中,而引用类型变量存储在栈内存中,保存的是实际对象在堆内存中的地址,实际对象中保存这内容。

3.自动装箱、自动拆箱

Java从jdk1.5开始引入自动装箱和拆箱,使得基本数据类型与引用类型之间相互转换变得简单。

自动装箱: java自动将原始类型转化为引用类型的过程,自动装箱时编译器会调用valueOf方法,将原始类型转化为对象类型。

自动拆箱: java自动将引用类型转化为原始类型的过程,自动拆箱时编译器会调用intValue(),doubleValue()这类的方法将对象转换成原始类型值。

自动装箱主要发生在两种情况:一种是赋值时,一种是方法调用时。

a.赋值

Integer a = 3; //自动装箱

int b = a; //自动拆箱
b.方法调用

public Integer query(Integer a){

return a;
}
query(3); //自动装箱
int result = query(3); //自动拆箱
4.自动装箱、拆箱带来的问题
1.程序的性能
由于装箱会隐式地创建对象创建,因此千万不要在一个循环中进行自动装箱的操作,下面就是一个循环中进行自动装箱的例子,会额外创建多余的对象,增加GC的压力,影响程序的性能:

Integer sum = 0;

for(int i=0; i<1000; i++){
sum+=i;
}
2.空指针异常
注意拆箱过程中可能产生的空指针异常,一个简单的例子:

Object obj = null;

int i = (Integer)obj;
3.对象相等比较时
先来看一个常见的例子:

Integer a = 120;

int b= 120;
Integer c = 120;
Integer d = new Integer(120);
System.out.println(a == b); //true t1
System.out.println(a == c); //true t2
System.out.println(a == d); //false t3

Integer e = 128;

Integer f = 128;
System.out.println(e == f); //false t4
返回结果是不是出乎大家的意料,解释一下每种结果的原因:
我们先反编译一下生成字节码:

Integer a = Integer.valueOf(120);

int b = 120;
Integer c = Integer.valueOf(120);
Integer d = new Integer(120);
System.out.println(a.intValue() == b);
System.out.println(a == c);
System.out.println(a == d);

Integer e = Integer.valueOf(127);

Integer f = Integer.valueOf(127);
System.out.println(e == f);

Integer e1 = Integer.valueOf(128);

Integer f1 = Integer.valueOf(128);
System.out.println(e1 == f1);
可以看到变量a、c在初始化的时候编译器调用了valueOf进行自动装箱,在a==b时对变量a调用了intValue()方法进行了自动拆箱操作,这就很好解释t1~t4的结果了。

t1产生的原因是编译器编译时会调用intValue()自动的将a进行了拆箱,结果肯定是true;

t2跟t4的结果比较难理解:这是因为初始化时,编译器会调用装箱类的valueOf()方法,查看jdk的源码:

public static Integer valueOf(int i) {

assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
发现jdk对-128~127之间的值做了缓存,对于-128~127之间的值会取缓存中的引用,通过缓存经常请求的值而显著提高空间和时间性能。
这就能解释t2结果返回true,而t4由于128不在缓存区间内,编译器调用valueOf方法会重新创建新的对象,两个不同的对象返回false。

t3结果无论如何都不会相等的,因为new Integer(120)构造器会创建新的对象。

Byte、Short、Integer、Long、Char这几个装箱类的valueOf()方法都会做缓存,而Float、Double则不会,原因也很简单,因为byte、Short、integer、long、char在某个范围内的整数个数是有限的,但是float、double这两个浮点数却不是。

转载于:https://www.cnblogs.com/fengda/p/10125970.html

你可能感兴趣的文章
性能测试之稳定性测试(可靠性测试)
查看>>
Flask02 路由的书写、蓝图、利用蓝图实现url前缀、利用蓝图实现子域名、访问静态文件...
查看>>
linux c lseek (空洞文件) 分析和处理
查看>>
String分析
查看>>
MySQL学习——SQL查询语句(连接查询&子查询)(三)
查看>>
oracle pl sql 行转列 (数据翻转实现)
查看>>
优秀的项目经理需要具备哪些品质?
查看>>
Avi视频生成缩略图时,提示“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”...
查看>>
命令行执行python模块时提示ImportError: No module named xxx
查看>>
WPF界面假死
查看>>
asp.net mvc 2.o 中使用JQuery.uploadify
查看>>
C#学习笔记2
查看>>
Java 面向对象 之 super 关键字
查看>>
Java 设计模式 之 观察者模式
查看>>
Failed to load JavaHL Library.
查看>>
HTML5的本地存储
查看>>
输入框实时模糊匹配输入
查看>>
Python3入门(四)——Python函数
查看>>
WPF中,使用ICollectionView进行排序时,汉字排序出现问题的解决
查看>>
YARN的设计
查看>>