zoukankan      html  css  js  c++  java
  • java中的equals与==的区别

    equals是Object类的公共方法,方法内部是用==实现的。但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同。而==是比较地址,但是基本数据类型,==比较的是两个变量的值是否相同,对于两个引用数据类型而言,==比较的是它们的地址是否相同。

    equals方法比较内容

    public class CSDN {
    	public static void main(String[] args) {
    		String s1 = "abc";
    		String s2 = "abc";
    		String s3 = new String("abc");
    		System.out.println("String:" + s1.equals(s2) + "," + s1.equals(s3));
    		
    		Byte a1 = new Byte((byte)1);
    		Byte b1 = new Byte((byte)1);
    		System.out.println("Byte:" + a1.equals(b1));
    		
    		Short a2 = new Short((short)1);
    		Short b2 = new Short((short)1);
    		System.out.println("Short:" + a2.equals(b2));
    		
    		Integer a3 = new Integer(1);
    		Integer b3 = new Integer(1);
    		System.out.println("Integer:" + a3.equals(b3));
    		
    		Long a4 = new Long(1L);
    		Long b4 = new Long(1L);
    		System.out.println("Long:" + a4.equals(b4));
    		
    		Float a5 = new Float(1.0f);
    		Float b5 = new Float(1.0f);
    		System.out.println("Float:" + a5.equals(b5));
    		
    		Double a6 = new Double(1.0d);
    		Double b6 = new Double(1.0d);
    		System.out.println("Double:" + a6.equals(b6));
    		
    		Boolean a7 = new Boolean(false);
    		Boolean b7 = new Boolean(false);
    		System.out.println("Boolean:" + a7.equals(b7));
    		
    		Character a8 = new Character('1');
    		Character b8 = new Character('1');
    		System.out.println("Character:" + a8.equals(b8));
    	}
    }
    
    输出:
    String:true,true
    Byte:true
    Short:true
    Integer:true
    Long:true
    Float:true
    Double:true
    Boolean:true
    Character:true

    ==比较地址

    1. 对于基本数据类型是比较它们的值,下面用int类型举例演示,其他基本数据类型一样的结果。

    public class CSDN {
    	public static void main(String[] args) {
    		int a = 1;
    		int b = 1;
    		System.out.println(a == b);
    	}
    }
    
    输出:
    true
    

    2. 对于引用数据类型,比较的是对象的地址是否相同。由于java的常量池机制,相同的字符串常量地址是一样的。

    public class CSDN {
    	public static void main(String[] args) {
    		String s1 = "abc";
    		String s2 = "abc";
    		String s3 = new String("abc");
    		String s4 = new String("abc");
    		System.out.println("String:" + (s1==s2) + "," +  (s1==s3) + "," +  (s3==s4));
    		
    		Byte a1 = new Byte((byte)1);
    		Byte b1 = new Byte((byte)1);
    		System.out.println("Byte:" + (a1==b1));
    
    		Short a2 = new Short((short)1);
    		Short b2 = new Short((short)1);
    		System.out.println("Short:" + (a2==b2));
    
    		Integer a3 = new Integer(1);
    		Integer b3 = new Integer(1);
    		System.out.println("Integer:" + (a3==b3));
    
    		Long a4 = new Long(1L);
    		Long b4 = new Long(1L);
    		System.out.println("Long:" + (a4==b4));
    
    		Float a5 = new Float(1.0f);
    		Float b5 = new Float(1.0f);
    		System.out.println("Float:" + (a5==b5));
    
    		Double a6 = new Double(1.0d);
    		Double b6 = new Double(1.0d);
    		System.out.println("Double:" + (a6==b6));
    
    		Boolean a7 = new Boolean(false);
    		Boolean b7 = new Boolean(false);
    		System.out.println("Boolean:" + (a7==b7));
    
    		Character a8 = new Character('1');
    		Character b8 = new Character('1');
    		System.out.println("Character:" + (a8==b8));
    		
    	}
    }
    
    输出:
    String:true,false,false
    Byte:false
    Short:false
    Integer:false
    Long:false
    Float:false
    Double:false
    Boolean:false
    Character:false

    解释下第一行输出的结果:由于java的常量池机制,s1和s2它们在常量池的地址是一样的。而s3是new出来的,需要在堆内存开辟空间,地址当然和s1,s2的不一样。

    下面看下几个拆箱装箱的例子

    public class CSDN {
    	public static void main(String[] args) {
    		Integer a = 100;
    		Integer b = 100;
    		int c = 100;
    		Integer d = new Integer(100);
    		
    		System.out.println("a == b :" + (a == b)); //a和b装箱,然后比较地址。
    		System.out.println("a.equals(b) :" + a.equals(b)); //a和b装箱,然后比较对象内容
    		System.out.println("a == c :" + (a == c)); // a先拆箱,然后再和c比较值
    		System.out.println("a.equals(c) :" + a.equals(c)); //c先装箱,然后比较对象内容
    		System.out.println("a == d :" + (a == d));  //d属于new出来的,地址和a肯定不一样
    		System.out.println("a.equals(d) :" + a.equals(d)); //a装箱,然后和d比较内容
    		System.out.println("d == c :" + (d == c)); //d拆箱,然后和c比较值
    		System.out.println("d.equals(c) :" + d.equals(c)); //c装箱,然后和d比较内容
    		
    	}
    }
    
    输出:
    a == b :true
    a.equals(b) :true
    a == c :true
    a.equals(c) :true
    a == d :false
    a.equals(d) :true
    d == c :true
    d.equals(c) :true

    简单来说,装箱就是将基本数据类型转换为包装器类型;拆箱就是将包装器类型转换为基本数据类型。

    例如:

    public class CSDN {
    	public static void main(String[] args) {
    		Integer a1 = 100; //自动装箱,相当于执行Integer a1 = Integer.valueOf(100);
    		int b1 = a1;      //自动拆箱,相当于执行int b1 = a1.intValue();
    	}
    }

    其中Integer.valueOf函数源码如下:

    public static Integer valueOf(int i) {
        if (i >= -128 && i <= 127)
            return IntegerCache.cache[i + 128];
        return new Integer(i);
    }

    而cache[]源码如下:数组中保存的是256个Integer对象。

    static final Integer cache[] = new Integer[256];

    也就是说,只要在自动装箱的过程中,值在-128到127之间,那么它们==的地址都是一样的。例如最上面的例子中下面这行代码:

    System.out.println("a == b :" + (a == b)); //a和b装箱,然后比较地址。

    如果值超过这个范围,那么在自动装箱时就会再开辟空间,地址就会不一样。例如:

    public class CSDN {
    	public static void main(String[] args) {
    		Integer a = 128; 
    		Integer b = 128; 
    		System.out.println(a == b);  
    		System.out.println(a.equals(b));  
    	}
    }
    
    输出:
    false
    true

    如果不理解就看看源码!






  • 相关阅读:
    Android开发进度07
    wifidog认证实现OpenWRT强制认证的WIFI热点
    wifidog配置分析
    wifidog源码
    Wifidog分析wifidog认证网关协议v1
    Wifidog认证稳定性测试方法及说明
    X86 DD-WRT WifiDog 配置详解
    wifidog无线认证RADIUS 配置指南
    wifidog配置DD-WRT中使用 RADIUS 对无线网络认证
    wifidog如何判断用户不在线?
  • 原文地址:https://www.cnblogs.com/neuzk/p/9476423.html
Copyright © 2011-2022 走看看