装箱就是 自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。
1、基本数据类型
基本数据类型只有8种,可按照如下分类
①整数类型:long、int、short、byte
②浮点类型:float、double
③字符类型:char
④布尔类型:boolean
No. | 数据类型 | 大小/位 | 可表示数据范围 | 默认值 |
---|---|---|---|---|
1 | byte (字节型) |
8 | -128~127 | 0 |
2 | short (短整型) |
16 | -32768~32767 | 0 |
3 | int (整型) |
32 | -2147483648~2147483647 | 0 |
4 | long (长整型) |
64 | -9223372036854775808~9223372036854775807 | 0 |
5 | float (单精度) |
32 | -3.4E38~3.4E38 | 0.0 |
6 | double (双精度) |
64 | -1.7E308~1.7E308 | 0.0 |
7 | char (字符) |
16 | 0~255 | 'u0000' |
8 | boolean (布尔) |
- | true或false | false |
基本数据类型 | 包装类 |
byte | Byte |
boolean | Boolean |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
简单的说包装类就是对基本数据类型的一个面向对象的封装,使其具有属性和方法(具体方法查看源码),符合面向对象的设计要求,JDK1.5提供了自动装箱(autoboxing)和自动拆箱(autounboxing)功能, 从而实现了包装类和基本数据类型之间的自动转换。
基本数据类型在不赋值的情况下具有默认值,而包装类是类在不创建对象时默认为null,例如:int的默认值为0,而Integer的默认值为null;
封装,是java这门语言的重要核心思想之一,封装也是对面向对象这一思想很好的体现。
包装的意义:在很多情况下,我们需要对数据进行一些转换,如:将一字符串"123"转换成int类型的123,或者将123转换成"123"这样的字符串,再或者,我们站在对象的角度,获取int类型所能表示的最大整数(Integer.MAX_VALUE)等等这些运用,都要用到基本数据类型的封装类。
.基本类型和封装类的相互转换(以int类型为例)
封装类转基本数据类型:
Integer integer = new Integer(3);
int num = integer.intValue();
当然,也可以直接 int num = integer,这里的自动拆箱,其实也是调用了封装类的intValue()方法来实现的。
- 进行 = 赋值操作(装箱或拆箱)
- 进行+,-,*,/混合运算 (拆箱)
- 进行>,<,==比较运算(拆箱)
- 调用equals进行比较(装箱)
- ArrayList,HashMap等集合类 添加基础类型数据时(装箱)
2、引用数据类型
引用数据类型非常多,大致包括:
类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
例如,String
类型就是引用类型。
简单来说,所有的非基本数据类型都是引用数据类型。
3、基本数据类型和引用数据类型的区别
1、存储位置
基本变量类型
- 在方法中定义的非全局基本数据类型变量的具体内容是存储在栈中的
引用变量类型
- 只要是引用数据类型变量,其具体内容都是存放在堆中的,而栈中存放的是其具体内容所在内存的地址
ps:通过变量地址可以找到变量的具体内容,就如同通过房间号可以找到房间一般
全局变量:定义在类里面的变量
局部变量:定义在方法里面的变量
全局变量可以不赋值,局部变量必须赋值,和他们所占内存有关
为什么全局变量可以不赋值?
全局变量在加载类的时候就初始化了。定义变量在内存中大小需要固定地址需要连续,全局变量需要时刻存储在变量表中,地址大小固定,它必须指向一个值,默认初始化的值是0.
而局部变量不知道什么时候调用所在方法,不需要时刻在变量表中,一旦需要调用所在方法的时候,局部变量也被调用,此变量也必须赋值,给他开辟一个空间,当不调用的时候会释放掉空间。
public class Main{ public static void main(String[] args){ //基本数据类型 int i=1; double d=1.2; //引用数据类型 String str="helloworld"; } }
传递方式
基本变量类型
- 在方法中定义的非全局基本数据类型变量,调用方法时作为参数是按数值传递的
//基本数据类型作为方法参数被调用 public class Main{ public static void main(String[] args){ int msg = 100; System.out.println("调用方法前msg的值: "+ msg); //100 fun(msg); System.out.println("调用方法后msg的值: "+ msg); //100 } public static void fun(int temp){ temp = 0; } }
引用变量类型
- 引用数据类型变量,调用方法时作为参数是按引用传递的,传递的是引用的副本
//引用数据类型作为方法参数被调用 class Book{ String name; double price; public Book(String name,double price){ this.name = name; this.price = price; } public void getInfo(){ System.out.println("图书名称:"+ name + ",价格:" + price); } public void setPrice(double price){ this.price = price; } } public class Main{ public static void main(String[] args){ Book book = new Book("Java开发指南",66.6); book.getInfo(); //图书名称:Java开发指南,价格:66.6 fun(book); book.getInfo(); //图书名称:Java开发指南,价格:99.9 } public static void fun(Book temp){ temp.setPrice(99.9); } }
调用时为temp在栈中开辟新空间,并指向book的具体内容,方法执行完毕后temp在栈中的内存被释放掉