持续创作,加速成长!这是我参与「掘金日新计划 · 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的习惯