Java中的包装类是什么
作者:Xucc_
Java包装类是什么
java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。
基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。
为了弥补这个缺陷,java提供了包装类。
包装类顾名思义就是将基本的数据类型以及一些辅助方法包装到类中,例如自己实现一个int的包装类:
class IntDemo { private int num; public IntDemo(int num) { this.num = num; } public int intValue() { return this.num; } }
1. Java提供的包装类
虽然上面的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
其中定义的方法如下:
其实Number中定义的方法就是用于拆箱装箱的。
2. 拆箱与装箱
- 装箱:
将基本数据类型封装为包装类对象,利用每一个包装类提供的构造方法实现装箱操作。
- 拆箱:
将包装类中包装的基本数据类型数据取出。
// 装箱 Integer integer1 = new Integer(1); // 拆箱 int integer2 = integer1.intValue();
JDK1.5之后提供自动拆装箱。
// 自动装箱 Integer integer1 = 1; // 自动拆箱 int integer2 = integer1;
3. 自动装箱的内存复用
自动装箱时,对于Integer var = ?,如果var指向的对象在-128 至 127 范围内的赋值时,生成的Integer实例化对象是由 IntegerCache.cache() 方法产生,它会复用已有对象。
和String的共享池操作是一个道理,cache()方法会将位于-128~127范围内产生的Integer对象入池,下次使用的时候,从池中拿去,就不会在创建了。
所以,在这个数值区间内的 Integer对象的栈指向(属性名) 可以直接使用==进行判断,因为值相同,指向的就是同一片区域。
但是这个区间之外的所有数据,自动装箱都会在堆上产生实例化,并不再复用已有对象,这是一个大坑,为了避免这个问题,推荐使用 equals 方法进行Integer的判断。
对于所有数值型的包装类来说,都会涉及到上面这种问题,一定要多加注意。
而对于手动装箱,即采用new进行包装类创建时,不会发生内存复用,因为new关键字每次使用,都会开辟新的空间,这和String采用构造方法创建字符串不入池相对应。
4. 包装类编码规约
所有的相同类型的包装类对象之间值的比较,全部使用equals()方法。
所有的POJO(简单Java类,只包含基本属性,有参构造,get/set)类属性必须使用包装类数据类型,类属性即static属性。
RPC(远程方法调用)方法返回值和参数必须使用包装数据类型。
推荐所有的局部变量使用基本数据类型。
5. 包装类对字符串与基本数据类型转换的支持
实际工程中,各种数据的接收是通常是通过字符串完成的,所以要掌握包装类对字符串转换的方法。
// String->int public static int parselnt(String s)throws NumberFormatException; // String->double public static double parseDouble(String)throws NumberFormatException; // String->Boolean public static boolean parseBoolean(String s)
字符串转数值类型时字符串只能包含数字,否则会抛出 NumberFormatException 异常,这是一个非受查异常。
但是字符串转Boolean是个特例,parseBoolean()方法会将”true”转为true,而将非”true”的字符串转为false。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。