JAVA基本类型和引用类型

Wesley13
• 阅读 690

一、基本数据类型

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对-128127之间的值做了缓存,对于-128127之间的值会取缓存中的引用,通过缓存经常请求的值而显著提高空间和时间性能。
这就能解释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这两个浮点数却不是。

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
这里我要明说一下,不是Java初级和学习Java的千万不要乱看,否则你会怀疑人生,因为会浪费你时间啊!!!本次考点是Java初级开发工程师面试必备的一些东西!!!1、数据类型基本类型cbyte/8、short/16、int/32、long/64、boolean/、char/16、float/32、double/64boolean只有两个值,true、f
Wesley13 Wesley13
3年前
java面试题
java整型默认为int,浮点型默认为doubel1.switch语句能否作用在byte上,能否作用在long上,能否作用在String上?   在switch(e)中,e只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于byte,short,char都可以隐含
Wesley13 Wesley13
3年前
java四类八种基本类型
整型byte字节型short短整型int            普通整型long长整型浮点型float        单精度double    双精度逻辑型boolean 只有true或者false两个值字符型char字符型
隔壁老王 隔壁老王
3年前
我的C语言基础
C语言32个关键字auto声明自动变量short声明短整型变量或函数int声明整型变量或函数long声明长整型变量或函数float声明浮点型变量或函数double声明双精度变量或函数char声明字符型变量或函数struct声明结构体变量或函数union声明共用数据类型enum声明枚举类型typedef用以给数据类型取别名co
Wesley13 Wesley13
3年前
java 知识点 小结
1. Java8种基本类型:byte char shortint long double float booleanByte:8位Short:16位Int:32位Long:64位Float:32位Double:64位2. ListsetmapList:有序;
Stella981 Stella981
3年前
JVM调优总结一
数据类型   Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。基本类型包括:byte,short,int,long,cha
Wesley13 Wesley13
3年前
Java基础(二)数据类型
  数据类型主要分为基本类型和引用类型两大类。  一、基本类型  1.基本类型又分为数值类型和boolean类型,  (1)数值类型包括浮点数类型、整数类型和字符类型  整型                                          浮点型(初始化时需要加f或d)  字符类型  byte    
小万哥 小万哥
1年前
Java基础知识:面试官必问的问题
数据类型基本类型byte/8char/16short/16int/32float/32long/64double/64boolean/boolean只有两个值:true、false,可以使用1bit来存储,但是具体大小没有明确规定。JVM会在编译时期将bo
小万哥 小万哥
5个月前
Kotlin 数据类型详解:数字、字符、布尔值与类型转换指南
Kotlin中变量类型由值决定,如Int、Double、Char、Boolean、String。通常可省略类型声明,但有时需指定。数字类型分整数(Byte,Short,Int,Long)和浮点(Float,Double),默认整数为Int,浮点为Double。布尔值是true或false,Char用单引号,字符串用双引号。数组和类型转换将在后续讨论,转换需用特定函数。