java包装类

136 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,[点击查看活动详情]

包装类基本知识

Java 是面向对象的语言,但并不是“纯面向对象”的,因为我们经常用到的基本数
据类型就不是对象。但是我们在实际应用中经常需要将基本数据转化成对象,以便于操
作。比如:将基本数据类型存储到 Object[ ]数组或集合中的操作等等

为了解决这个不足, Java 在设计类时为每个基本数据类型设计了一个对应的类进行
代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

Integer类

创建Integer对象

Integer i=new Integer(10);
Integer i=Integer.valueOf(50);

以上两种创建的方法都可以创建对象,建议使用第二种方法,第一种方法在jdk9中已经被弃用
将Integer类对象转换为其他类型

int a=i.intValue(); #转换为int类型
double b=i.doubleValue(); #转换为double类型

将字符串转为数字

Integer i=Integer.valueOf("50");

java中重写了valueOf代码,可以支持字符串的转换

自动装箱和自动拆箱

作用: 自动装箱(autoboxing)和拆箱(unboxing):将基本数据类型和包装类自动转换
自动装箱

Integer i=100;
Integer i=Integer.valueOf(100);

第一条语句执行时候本应该是报错,但是可以正常运行的原因是因为java进行了自动装箱,实际上是执行了第二条语句

自动拆箱

Integer i=Integer.valueOf(100);
int x=i;
int x=i.intValue();

第二条语句相当于执行了第三条语句,这就是自动拆箱,将Integer类型转换为基础类型

空指针异常问题

Integer i=null;
int j=i;

这种情况会报错,因为int不能接收空值

包装类的缓存问题

我们看下面一段代码

        Integer a=100;
        Integer b=100;
        Integer i=10000;
        Integer j=10000;
        System.out.println(a==b);
        System.out.println(i==j);
        System.out.println(a.equals(b));
        System.out.println(i.equals(j));

观察运行结果

理论上讲==判断在判断对象时应该判断的是内存地址,所以对于对象来说每new一个都不一样,但是却反悔了true,因为这是自动封箱,于是原因一定在Integer.valueOf()函数中

发现他有一个if判断,当在判断不属于某一个范围时,他才会返回一个对象,否则返回一个cache

跟入cache发现,当处于-128到127时间,他会直接返回数组中的元素

这里也将元素存入了数组,于是是直接返回的数字没有创建对象,到此问题解决

String类

创建方法String i=new String();

较为简单,注意一个小细节

String str1 = "hello" + " java";//相当于 str1 = "hello java";
String str2 = "hellojava";
System.out.println(str1 == str2);//true
String str3 = "hello";String str4 = " java";
//编译的时候不知道变量中存储的是什么,所以没办法在编译的时候优化
String str5 = str3 + str4;
System.out.println(str2 == str5);//false

StringBuffer和StringBuilder

StringBuffer 线程安全,做线程同步检查, 效率较低。
StringBuilder 线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。

StringBuffer常用方法

重载的 public StringBuilder append(…)方法

StringBuilder a=new StringBuilder();
a.append('a').append('b');
System.out.println(a); //ab

方法 public StringBuilder delete(int start,int end)

StringBuilder a=new StringBuilder();
a.append('a').append('b');
a.delete(0,1);
System.out.println(a); //b

字符序列陷阱和时间和空间效率测试

        String str8 = "";
        long num1 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
        long time1 = System.currentTimeMillis();//获取系统的当前时间
        for (int i = 0; i < 5000; i++) {
            str8 = str8 + i;//相当于产生了 5000 个对象
        }
        long num2 = Runtime.getRuntime().freeMemory();
        long time2 = System.currentTimeMillis();
        System.out.println("String 占用内存 : " + (num1 - num2));
        System.out.println("String 占用时间 : " + (time2 - time1));
        StringBuilder sb1 = new StringBuilder("");
        long num3 = Runtime.getRuntime().freeMemory();
        long time3 = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            sb1.append(i);
        }
        long num4 = Runtime.getRuntime().freeMemory();
        long time4 = System.currentTimeMillis();
        System.out.println("StringBuilder 占用内存 : " + (num3 - num4));
        System.out.println("StringBuilder 占用时间 : " + (time4 - time3));

我们发现String和StringBuilder相差时间很大,于是拼接字符串务必养成append的习惯