JAVA SE面向对象编程(语法糖之自动装箱和拆箱)
1.java程序判断连个对象是否相等,一般有两种方式:==和equals
a.对于==,若两个对象是基本类型中的数值类型(不需要数值类型相同),值相等就返回true;若两个对象是泛型,指向同一对象返回true
b.equals方法是Object提供的实例方法。若不重写,则与==同,需要指向同一对象是返回true。
2.包装类与String相互转换
3.包装类比较
a.若包装类与数值类型的值比较,实际上取包装类实例包装的值与数值类型的值比较
b.两包装类实例做==比较,只有连个包装类型指向同一对象时返回true;equals比较,值相等返回true(包装类重写类equals方法)
4.对于Integer,会将-128~127的整数自动装箱城Integer实例(可参考链接:自定义缓存实例的不可变类)
a.使用Integer a =1相当于Integer.valueOf(1);从缓存中取Integer实例
b.使用Integer a = new Integer(1);就是新建Integer的实例,不从缓存中取数据
特别说明:第3个总结中,可能有点绕,这其实有一个包装类和基础数据类型的自动装箱和拆箱的过程。将基础类型自动装箱成包装类型,是java语言提供了语法糖支持,在将.java文件变成成.class字节码文件时,自动使用了XXX.valueOf方法;而将包装类型拆箱成基础类型,则是自动调用了XXX.xxxValue方法
自动装箱例子:
public class PackagClass { public static void main(String[] args) { Integer a =1; } }
使用javap -c PackagClass.class,可以看到字节码如下
Compiled from "PackagClass.java" public class main.genericity.PackagClass { public main.genericity.PackagClass(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_1 1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: astore_1 5: return }
在这段字节码中,着重看一下
这个是一个自动装箱的过程
自动拆箱例子:
public class PackagClass { public static void main(String[] args) { Integer a =Integer.valueOf(1); System.out.println(a>0); } }
同样的使用javap -c PackagClass.class,可以看到字节码如下
public class main.genericity.PackagClass { public main.genericity.PackagClass(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_1 1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: astore_1 5: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 8: aload_1 9: invokevirtual #4 // Method java/lang/Integer.intValue:()I 12: ifle 19 15: iconst_1 16: goto 20 19: iconst_0 20: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V 23: return }
在这段字节码中,着重看一下
这个是一个自动拆箱的过程
那什么时候会进行装箱,什么使用进行拆箱呢?
简单点说,就是一个基本类型的数据要当成对象使用时(基本类型是没用方法的,用到方法的都是对象),自动装箱;
对象当初基本类型做运行的使用(+,-,*,/等)就自动拆箱。
这个地方要注意一点,基本类型和对象都可以使用==,因此使用==两边都是基本类型,或者都是包装类型,就不会进行自动装箱和拆箱操作,若一边是基本类型,一边是包装类型,包装类型自动拆箱成基本类。
再就是使用Integer的使用,注意-128~127有缓存就行
最后在补充下equals方法发,对于Integer底层(Double等一样)
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
首先判断是不是相同类型,如果是,则拆箱进行比较,如果不是,返回false
面试题中经常会有这样的问题,个人觉得理解了这一点知识,无论面试题怎么变,就都不会搞错的。
在例子13后面我进行了一个简单的例子说明,希望通过这样例子的说明,能让看到我写的内容的人能更加容易理解,希望能共同进步。
题目:
1.判断下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { String a ="疯狂JAVA"; String b="疯狂"; String c="JAVA"; String d=b+c; System.out.println(a==d); } }
2.判断下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { String a ="疯狂JAVA"; final String b="疯狂"; final String c="JAVA"; String d=b+c; System.out.println(a==d); } }
3.判断下面程序的返回结果
public class StringCompareTest { public static void main(String[] args) { String s1 = "疯狂Java"; String s2 = "疯狂"; String s3 = "Java"; String s4 = "疯狂" + "Java"; String s5 = "疯" + "狂" + "Java"; String s6 = s2 + s3; String s7 = new String("疯狂Java"); System.out.println(s1 == s4); System.out.println(s1 == s5); System.out.println(s1 == s6); System.out.println(s1 == s7); } }
4.判断下面程序的返回结果
public class EqualTest { public static void main(String[] args) { int it = 65; float fl = 65.0f; System.out.println("65和65.0f是否相等?" + (it == fl)); char ch = 'A'; System.out.println("65和'A'是否相等?" + (it == ch)); String str1 = new String("hello"); String str2 = new String("hello"); System.out.println("str1和str2是否相等?" + (str1 == str2)); System.out.println("str1是否equals str2?" + (str1.equals(str2))); System.out.println("hello" == new EqualTest()); } }
5.定义一个EqualsOverWriteTest,并重写equals方法
6.判断下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Integer a = Integer.valueOf(6); System.out.println(a > 5.0); } }
7.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Double a = Double.valueOf(6.0); double b = 6.0; System.out.println(a==b); } }
8.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Double a = Double.valueOf(6.0); Double b = 6.0; System.out.println(a==b); } }
9.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Double a = Double.valueOf(6.0); Double b = 6.0; System.out.println(a.equals(b)); } }
10.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Integer ina = 2; Integer inb = 2; System.out.println(ina == inb); Integer biga = 128; Integer bigb = 128; System.out.println(biga == bigb); } }
11.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { int a =128; Integer b =128; Integer c = 128; System.out.println(a==b); System.out.println(a==c); System.out.println(b==c); } }
12.给出下面程序的返回结果
public class BaseDataType { public static void main(String[] args) { Integer ina = 2; Integer inb = new Integer(2); Integer inc = Integer.valueOf(2); System.out.println(ina == inb); System.out.println(ina == inc); } }
13.给出下面程序的返回结果
public class PackageClass { public static void main(String[] args) { Integer a =1; Integer b=2; Integer c =3; Integer d =3; Integer e = 321; Integer f = 321; Long g = 3L; Integer h = 320; System.out.println(c==d); System.out.println(e==f); System.out.println(c==(a+b)); System.out.println(c.equals(a+b)); System.out.println(g==(a+b)); System.out.println(g.equals(a+b)); System.out.println(e==(a+h)); System.out.println(f==(a+h)); } }
ps:例13中说明下System.out.println(c==(a+b));可以这样解释,a和b包装类型,要进行+号运行,都进行拆箱,在相加,得到int类型数据,值为3。==前面c为包装类型,==后面为新生成的基本类型int(值为3),包装类型和基本类型==比较,包装类c数据自动进行拆箱,两个基本类型int最后做==比较。至于说其他的结果到底是怎么得来的,根据这个思路是一样的,就不多写了。
答案
1.false
2.true
3.true true false false
4.true true false true 报错
5.
6.true
7.true
8.false
9.true
10.true false
11.true true false
12 false true
13
posted on 2020-03-27 10:21 xingshouzhan 阅读(204) 评论(0) 编辑 收藏 举报