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编辑  收藏  举报

导航