zoukankan      html  css  js  c++  java
  • ==和equals方法:

    Java程序中判断两个变量是否相等有两种方式:

    一、利用 == 运算符:

      1.1、如果两个变量是基本类型变量,且都是数值型(不一定要求数值类型完全相同),则只要两个变量的值相同,就返回true

      1.2、对于两个引用类型变量,只有它们指向同一个对象时,== 判断才会返回true

      1.3、== 运算符不可用于比较类型上没有父子关系的对象

    代码示例:

    import static java.lang.System.*;
    public class EqualTest{
    	public static void main(String[] args){
    		int it=65;
    		float f1=65.0f;
    		out.println("65和65.0f是否相等?"+(it==f1));
    
    		char ch='A';
    		out.println("65和A是否相等?"+(it==ch));
    
    		String str1=new String("hello");
    		String str2=new String("hello");
    		out.println("str1和str2是否相等?"+(str1==str2));
    		out.println("str1是否equals str2?"+(str1.equals(str2)));
    
    		//-由于java.lang.String与EqualTest类没有继承关系,下面代码会编译错误
    		//out.println("hello"==new EqualTest());
    	}
    }
    

     运行结果:

    知识点拓展:

      1、String str=“hello”;

      2、String str=new String("hello");

      如上两行代码中的两个变量str的区别:

      1行代码中的“hello”被称为 字符串直接量(在编译时就计算出来的字符串值),JVM通过 常量池 来管理这些字符串

      2行中的 new String("hello"),当使用这种定义方式时,JVM会先使用常量池来管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中,

      换句话说,new String("hello") 一共产生了两个字符串对象

    常量池(constant pool):专门用于管理在编译时被确定并被保存在已编译的.class文件中的一些数据,包括了关于类、方法、接口中的常量,还包括字符串常量,如下代码示例:

    import static java.lang.System.*;
    public class CompareTest{
    	public static void main(String[] args){
    //-a直接引用常量池中的"张三李四" String a="张三李四"; String b="张三"; String c="李四"; //-d后面的字符串值在编译时就确定下来了 //-d直接引用常量池中的"张三李四" String d="张三"+"李四"; //-e后面的字符串值在编译时就确定下来了 //-e直接引用常量池中的"张三李四" String e="张"+"三"+"李四"; //-f后面的字符串值不能在编译时就确定下来了 //-f不能直接引用常量池中的字符串 String f=b+c; //-使用new调用构造器会重新创建一个新的String对象 //-g引用堆内存中新创建的String对象 String g=new String("张三李四"); out.println(a==d);//-true out.println(a==e);//-true out.println(a==f);//-false out.println(a==g);//-false } }

     总结:

    1、JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本

    2、例如上面代码中a、d、e所引用的字符串可以在编译期就确定下来,因此他们都将引用常量池中同一个字符串对象,所以用 == 运算符计算是返回 true 的

    3、使用 new String()创建的字符串对象是运行时创建出来的,它被保存在运行时内存区内(即堆内存内),不会放入常量池中

    二、利用 equals()方法:

    1、equals()方法是Object类提供的一个实例方法,所有引用变量都可以引用这个方法判断与其它引用变量是否相等

    2、判断是否相等的标准与 == 没有区别,都是看引用变量是否指向相同的对象,从这个作用上来说equals()方法没有太大意义

    3、equals()方法最大的意义是可通过重写该方法,实现自定义的相等判断,如:String类就重写了equals()方法:只要两个字符串所包含的字符序列相等,即判断相等,返回true

    重写equals()方法,实现两个类相等:

    class Person{
    	//-重写Object类的equals()方法
    	public boolean equals(Object o){
    		//-相等规则自己定义
    		return true;
    	}
    }
    
    class Dog{
    	//-空类
    }
    
    public class OverrideEquals{
    	public static void main(String[] args){
    		Person p=new Person();
    		System.out.println(p.equals(new Dog()));
    		System.out.println(p.equals(new String("张三")));
    
    	}
    }
    

     运行结果:

    有意义的去判断两个类相等。代码示例:

    class Penson{
    	private String name;
    	private String id;
    	
    	public Penson(){
    		
    	}
    
    	public Penson(String name,String id){
    		this.name=name;
    		this.id=id;
    	}
    	
    	public void setName(String name){
    		this.name=name;
    	}
    
    	public String getName(){
    		return this.name;
    	}
    
    	public void setId(String id){
    		this.id=id;
    	}
    
    	public String getId(){
    		return this.id;
    	}
    
    	public boolean equals(Object obj){
    		if(this==obj){
    			return true;
    		}
    
    		//-obj.getClass()==Penson.class用到了反射基础,暂时不用深究
    		if(obj!=null&&obj.getClass()==Penson.class){
    			//-强制转换,把将要比较的参数转换成Penson类,便于后面获取类变量id
    			Penson penson=(Penson)obj;
    			//-只有两个对象的id相等,才判定相等
    			if(this.getId().equals(penson.getId())){
    				return true;
    			}
    		}
    		return false;
    	}
    }
    
    public class OverrideEqualsRight{
    	public static void main(String[] args){
    		Penson p1=new Penson("张三","9527");
    		Penson p2=new Penson("李四","9527");
    		Penson p3=new Penson("王五","9526");
    		//-p1与p2的id相等,返回true
    		System.out.println(p1.equals(p2));
    		//-p1与p2的id不等,返回false
    		System.out.println(p1.equals(p3));
    	}
    }
    

     运行结果:

    通常而言,重写equals()方法应满足下面的条件:

    1、自反性:对任意x,x.equals(x)一定返回true

    2、对称性:对任意x、y,如果x.equals(y)返回true,那么y.equals(x)一定返回true

    3、传递性:对任意x、y、z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)一定返回true

    4、一致性:对任意x、y,如果对象中用于等价比较的信息值没有发生改变,那么无论调用x.equals(y)多少次,返回的结果应该始终保持一致,要么一直true,要么一直false

    5、对任何不是null的x,x.equals(null)一定返回false

  • 相关阅读:
    一本书
    在linux oracle 10g/11g x64bit环境中,goldengate随os启动而自己主动启动的脚本
    关于仿酷狗音乐播放器开源:寻求一套音乐播放器素材,让仿酷狗开源
    Cocos2d-x中Vector<T>容器以及实例介绍
    成都传智播客Java/PHP培训就业率高
    P1341 无序字母对
    P1168 中位数
    P1146 硬币翻转
    P1340 兽径管理
    P2023 [AHOI2009]维护序列
  • 原文地址:https://www.cnblogs.com/baby-zhude/p/8052829.html
Copyright © 2011-2022 走看看