为什么需要包装类?

首先,Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,将每个基本数据类型设计一个对应的类进行代表,这种方式增强了Java面向对象的性质。

其次,如果仅仅有基本数据类型,那么在实际使用时将存在很多的不便,很多地方都需要使用对象而不是基本数据类型。比如,在集合类中,我们是无法将int 、double等类型放进去的,因为集合的容器要求元素是Object类型。而包装类型的存在使得向集合中传入数值成为可能,包装类的存在弥补了基本数据类型的不足。

此外,包装类还为基本类型添加了属性和方法,丰富了基本类型的操作。如当我们想知道int取值范围的最小值,我们需要通过运算,如下面所示,但是有了包装类,我们可以直接使用Integer.MAX_VALUE即可。

//求int的最大值
int max = 0;
int flag = 1;
for (int i=0; i<31; i++) {
	max += flag;
	flag = flag << 1;
}
System.out.println(max +"	"+ Integer.MAX_VALUE); //2147483647      2147483647

包装类的2种主要用途:

java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。

  • 作为 和基本数据类型对应的类 类型存在,方便涉及到对象的操作。
  • 包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

为什么要保留基本数据类型?

我们都知道在Java语言中,用new关键字创建的对象是存储在堆里的,我们通过栈中的引用来使用这些对象,所以,对象本身来说是比较消耗资源的。对于经常用到的类型,如int等,如果我们每次使用这种变量的时候都需要new一个对象的话,就会比较笨重了。所以,Java提供了基本数据类型,这种数据的变量不需要使用new在堆上创建,而是直接在栈内存中存储,因此会更加高效。

包装类(wrapper class/ラッパークラス),自动拆箱,自动装箱,基本类型与字符串之间的转换

Java中的包装类

JAVA中包装类的作用

Java 包装类是什么

Java数据类型

java使用包装类型合理的场景 java包装类的好处_基本类型

Java常量

类型

含义

数据举例

整数常量

所有的整数

0,1, 567, -9

小数常量

所有的小数

0.0, -0.1, 2.55

字符常量

单引号引起来,只能写一个字符,必须有内容

‘a’ , ’ ', ‘好’

字符串常量

双引号引起来,可以写多个字符,也可以不写

“A” ,“Hello” ,“你好” ,“”

布尔常量

只有两个值(流程控制中讲解)

true , false

空常量

只有一个值(引用数据类型中讲解)

null

package ArrayTest;

public class Array10 {
    char a;
    public static void main(String[] args) {
       new Array10().re();
    }
    public void re(){
        System.out.println("a = " + a);
        System.out.println(a==0);
        System.out.println(a=='\u0000');
        System.out.println(a==null);//编译报错
    }
}

java使用包装类型合理的场景 java包装类的好处_java_02

‘\u0000’~'\UFFFF’是什么意思

范围:0到65535。它不过对应的是unicode的编码值,即全球语言统一编码。

\u开头的是一个Unicode码的字符,每一个’\u0000’都代表了一个空格。

通常中文在的显示都是被转化为Unicode显示的。

Java变量

  • 基本数据类型:整数、浮点数、字符、布尔
  • 引用数据类型: 类、数组、接口

数据类型

关键字

内存占用

取值范围

字节型

byte

1个字节

-128 至 127

短整型

short

2个字节

-32768 至 32767

整型

int

4个字节

-231 至 231-1

长整型

long

8个字节

-263 至 263-1

单精度浮点数

float

4个字节

1.4013E-45 至 3.4028E+38

双精度浮点数

double

8个字节

4.9E-324 至 1.7977E+308

字符型

char

2个字节

0 至 216-1

布尔类型

boolean

1个字节

true,false

Java提供的包装类

class IntDemo {
    private int num;
    public IntDemo(int num) {
        this.num = num;
    }
    public int intValue() {
        return this.num;
    }
}

虽然上面的IntDemo类能实现一些辅助功能,而且可以支持泛型反射等功能,但是如果如果每次使用都自己封装这么一个类的话,就太繁琐了。所以,java为我们提供了基本数据类型的包装类,这些包装类分为两类,一种是对象型包装类,不继承任何其他类(Object的直接子类),另一种是数值型包装类,继承于Number类。

对象型(Object 的直接子类)包装类:

// boolean的包装类
public final class Boolean implements java.io.Serializable, Comparable<Boolean>

// char的包装类
public final class Character implements java.io.Serializable, Comparable<Character>

数值型(继承了Number类)包装类:

// byte的包装类
public final class Byte extends Number implements Comparable<Byte>

// short的包装类
public final class Short extends Number implements Comparable<Short> 

// int的包装类
public final class Integer extends Number implements Comparable<Integer>

// long的包装类
public final class Long extends Number implements Comparable<Long> 

// float的包装类
public final class Float extends Number implements Comparable<Float> 

// double的包装类
public final class Double extends Number implements Comparable<Double>

Boolean和Character两个类就是正常的属性方法封装,但是数值型的包装类继承了一个Number类。

public abstract class Number implements java.io.Serializable

其中定义的方法如下:

java使用包装类型合理的场景 java包装类的好处_java使用包装类型合理的场景_03

Java装箱拆箱

  • 装箱:从基本类型转换为对应的包装类对象。int→Integer
  • 拆箱:从包装类对象转换为对应的基本类型。Integer→int

手动装箱拆箱

// 装箱
Integer integer1 = new Integer(1);
//或者
Integer i2 = Integer.valueOf(4);
// 拆箱
int integer2 = integer1.intValue();

自动装箱拆箱

由于我们经常要做基本类型与包装类之间的转换,sun公司发现这样写比较麻烦,于是从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。

自动装箱:可以直接把一个基本类型的数据赋值给自己对应的包装类型。

自动拆箱:可以直接把一个包装类型的数据赋值给自己对应的基本类型。

// 自动装箱
Integer integer1 = 1;
Integer i = 4;//相当于i = Integer.valueOf(4);

// 自动拆箱
int integer2 = integer1; 
i = i + 5;//相当于i.intValue() + 5;

基本类型与字符串之间的转换

基本类型转字符串

  1. 可以直接使用+号
  2. 使用String类中的valueOf()方法
  3. 使用对应的包装类中重载的toString()方法

byte、short、char–>int–>long–>float–>double

public class Demo01 {
    public static void main(String[] args) {
       //使用+完成基本数据类型到字符串的转换
        int x=123;
        String s=x+"";
        
        //使用String类中的valueOf
        int i = 1;
        String s1 = String.valueOf(1.2);
        String s2 = String.valueOf(true);
        String s3 = String.valueOf(i);
        String s0 = String.valueOf('a');
        
        int j = 2;
        byte x = 2;
        short y = 2;
        long l =2;
        //使用对应的包装类中重载的toString方法
        String s8 = Byte.toString(x);
        String s9 = Byte.toString((byte) 2);
        String s13 = Short.toString(y);
        String s12 = Short.toString((short) 3);
        String s14 = Long.toString(l);
    }
}

字符串转换成对应的基本类型

  • 字符串转成基本类型使用包装类中的parseXxxx方法。

public static int parseInt(String s):将字符串参数转换为对应的int基本类型

  • 后期学习中遇到和parse相关的函数,都是把字符串解析成其他的数据。
  • 使用parseXxxx方法把一个字符串转成基本数据类型的时候,前提是这个字符串一定能够被转成对应的基本类型,否则会发生NumberFormatException异常。
package com.web;

public class Test43 {
    public static void main(String[] args) {
       //字符串转成基本类型使用包装类中的parseXxxx方法
        int num = Integer.parseInt("100");
        byte b1 = Byte.parseByte("2");
        byte b3 = Byte.parseByte("a");
        short sh = Short.parseShort("2");
    }
}