JAVA的基本数据类型有八种,但是这八种全不是面向对象的,然而Java却是一门面向对象的语言,这在实际使用时有很多的不便之处,所以为了解决这个短板,设计者将每个基本数据类型单独封装成一个类,这八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
什么是自动装箱,自动拆箱
自动装箱:把基本类型用它们对应的包装类包装起来,使它们具有对象的特质.自动装箱时编译器调用valueOf将原始类型值转换成对象
Integer i0 = new Integer(0); Integer i1 = 2; //自动装箱 Integer i1_ = Integer.valueOf(2);//上一行的本质其实是本行代码!
自动拆箱:跟自动装箱的方向相反,将Integer及Double这样的包装类的对象重新简化为基本类型的数据。 自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值
int a = i1+2;
这段代码就使用了自动拆箱。i1是我们上面通过自动装箱得到的一个integer对象,而这个对象是不能直接进行四则运算的,但是我们却让它加2,所以需要将将integer对象转变为基本数据类型(int),这个过程就是自动拆箱的过程。
为什么会有自动装箱和自动拆箱:
1. 我感觉就是因为懒,如果没有自动装箱/拆箱那么我们把的代码是:
Integer i = new Integer(2);//假如需要一个integer的对象i,值为2 int b=i.intValue();//又需要一个int型的值,大小与i相等
这是有了自动装箱,自动拆箱:
Integer i = 2; int b=i;
这样写起来方便了很多.
2.自动装箱的过程其实还可以起到节约内存的作用。我们先看一个例子:
Integer a = 1; Integer b = 1; Integer c = 144; Integer d = 144; Integer a1 = new Integer(1); Integer b1 = new Integer(1); System.out.println(a == b); //true System.out.println(a.equals(b)); //true System.out.println(a1 == b1); //false System.out.println(a1.equals(b1)); //true System.out.println(c == d); //false System.out.println(c.equals(d)); //true
前面四个没有任何问题,但是第五个难道不是true吗?怎么是个false呢?我写错了?不是的.
原因是: 在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象 。而如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。
Integer自动装箱池的范围是-128~127
Byte,Short,Long自动装箱池的范围是-128~127
Character自动装箱池的范围是0~127
Float和Double没有自动装箱池
2019.08.13 修改:
这里其实是用到了常量池:,可以参考: JAVA常量池的理解,此处就不修改了.
自动装箱的弊端:
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能.
Integer sum = 0; for(int i=1000; i<5000; i++){ sum+=i; }
上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下
int result = sum.intValue() + i; Integer sum = new Integer(result);
由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。
如何使用自动装箱,自动拆箱呢?
通过上面的几行简单代码大家应该会使用自动装箱,自动拆箱呢了,很简单,但是还有一个地方需要注意下.
Integer a = null; int b = a;
这两行代码完全是符合java语法规范的,编译也可以正常通过,但是运行的时候会抛出空指针异常。所以在这里提醒大家,在使用自动拆箱时,一定要确保包装类的引用不为空。
最后自总结下基本数据类型和包装类之间的转换:
package com.asa.java; import org.junit.Test; public class TestString { /* * 1.字符串 与基本数据类型、包装类之间转换 * ①字符串 --->基本数据类型、包装类:调用相应的包装类的parseXxx(String str); * ①基本数据类型、包装类--->字符串:调用字符串的重载的valueOf()方法 * * 2.字符串与字节数组间的转换 * ①字符串---->字节数组:调用字符串的getBytes() * ②字节数组---->字符串:调用字符串的构造器 * * 3.字符串与字符数组间的转换 * ①字符串---->字符数组:调用字符串的toCharArray(); * ②字符数组---->字符串:调用字符串的构造器 */ @Test public void test5(){ //1.字符串 与基本数据类型、包装类之间转换 String str1 = "123"; int i = Integer.parseInt(str1); System.out.println(i); String str2 = i + ""; str2 = String.valueOf(i); System.out.println(str2); System.out.println(); //2.字符串与字节数组间的转换 String str = "abcd123"; byte[] b = str.getBytes(); for(int j = 0;j < b.length;j++){ System.out.println((char)b[j]); } String str3 = new String(b); System.out.println(str3); System.out.println(); //3.字符串与字符数组间的转换 String str4 = "abc123中国人"; char[] c = str4.toCharArray(); for(int j = 0;j < c.length;j++){ System.out.println(c[j]); } String str5 = new String(c); System.out.println(str5); }
package com.abab.java; import org.junit.Test; //包装类:8种基本数据类型对应着一个类,此类即为包装类。 //基本数据类型 包装类 及String之间的相互转换 public class TestWrapper { //基本数据类型、包装类与String类之间的转换 @Test public void test2(){ //基本数据类型、包装类 --->String类:调用String类的重载的valueOf(Xxx x)方法 int i1 = 10; String str1 = i1 + "";//"10" Integer i2 = i1; String str2 = String.valueOf(i2); String str3 = String.valueOf(true);//"true" str2 = i2.toString(); System.out.println(str3); //String类--->基本数据类型、包装类:调用包装类的parseXxx(String str)方法 int i3 = Integer.parseInt(str2); System.out.println(i3); boolean b1 = Boolean.parseBoolean(str3); System.out.println(b1); //int i4 = (int)str2; } //基本数据类型与包装类之间的转化 @Test public void test1(){ int i = 10; System.out.println(i); boolean b = false; //基本数据类型--->对应的包装类:调用包装类的构造器 Integer i1 = new Integer(i); System.out.println(i1.toString()); Float f = new Float("12.3F"); System.out.println(f); //java.lang.NumberFormatException //i1 = new Integer("12abc"); //System.out.println(i1); //对于Boolean来讲,当形参是"true"返回true,除此之外返回false。 Boolean b1 = new Boolean("false"); System.out.println(b1); b1 = new Boolean("true"); System.out.println(b1); Order o = new Order(); System.out.println("$ "+o.b);//null //包装类--->基本数据类型:调用包装类Xxx的XxxValue()方法。 int i2 = i1.intValue(); System.out.println(i2); float f1 = f.floatValue(); System.out.println(f1); boolean b2 = b1.booleanValue(); //JDK5.0以后,自动装箱和拆箱 int i4 = 12; Integer i3 = i4;//自动装箱 Boolean bb = false; int i5 = i3;//自动拆箱 } } class Order{ Boolean b; }
还没有评论,来说两句吧...