Java的toString方法和==和equals方法(6.2)

1 toString方法
用System.out.println§;(p为people类的对象)直接输出对象p时,输出了一个’类名+@ +hashCode值’
System.out的println()方法为什么只能在控制台输出字符串,而p为一个对象,怎么能转换为字符串输出呢?实际上输出的是toString方法的返回值
toString方法是Object类的一个实例方法,因为所有类都是Object类的子类,所以所有类都有toString方法。toString方法返回一个字符串,是用于描述对象信息的一个方法。

//下面两行代码效果完全一样
System.out.println(p);
System.out.println(p.toString());

当直接输出对象时,就输出了该对象的自我描述信息,若要返回有参考价值的信息,需要在类中重写该方法。

//上面定义了一个苹果类,有 color,weight属性
//重写toString方法
public String toString()
{
   return "一个苹果的颜色是" + color
      + "重量是," + weight;
}

2 ==和equals方法
Java程序中测试两个变量是否相等有两种方式,一种是==,一种是equals()方法
(1)

  1. 当用==来判断两个变量是否相等时,,如果两个变量是基本类型,且都是数值型(不一定要求数据类型严格相等,比如65与65.0相等),则只要两个变量的值相等,就返回true。
    但对于两个引用变量,只有他们同时指向同一对象时,才会返回true,==不可用于比较类型上没有父子关系的两个对象

  2. String还有一个让人迷惑的地方:“hello”直接量和new Striing(“hello”)有什么区别?
    当使用形如“hello”的字符串直接量(包括在编译时就能计算出来的字符串值)时,JVM将会使用常量池来管理这些字符串;当使用new Striing(“hello”)时,JVM会先使用常量池来管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的对象将被保存在堆内存当中。换句话说,new Striing(“hello”)一共产生了两个字符串对象
    常量池(constant pool)专门用于管理在编译时被确定并保存在已编译的.class文件中的一些数据。它包含了关于类,方法,接口中的常量,还包括字符串常量。JVM保证相同的直接量只有一个,不会产生多个副本。

但是在很多情况下又希望,当判断两个引用变量时,只要满足类似于”值相等“的判断规则,并不要求两个引用变量指向同一个对象。此时就需要用到equals()方法了。

(2)
equals()方法是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法。但Object类默认的equals()方法与==没有任何区别,同样要求两个引用变量指向同一对象才会返回true。如果想实现”值相等“就返回true的规则。就需要在两个引用变量对应的类里重写该方法。
注意:String类已经重写了Object类的equals()方法,String的equals()方法的判断规则是:只要两个字符串所包含的字符串序列相同,就返回true。

class Person
{
   private String name;
   private String idStr;
   public Person(){}
   public Person(String name , String idStr)
   {
      this.name = name;
      this.idStr = idStr;
   }
   // 此处省略name和idStr的setter和getter方法   
   //重写equals方法,提供自定义的相等标准   
   public boolean equals(Object obj)
   {
      // 如果两个引用变量指向同一个对象      
      if (this == obj)
         return true;
      //只有当obj是Person对象时      
      if (obj != null && obj.getClass() == Person.class)
      {
         Person personObj = (Person)obj;
         // 并且当前对象的idStr与obj对象的idStr相等时才可判断相等
         //下面代码利用了反射基础
         if (this.getIdStr().equals(personObj.getIdStr()))
         {
            return true;
         }
      }
      return false;
   }
}
public class OverrideEqualsRight
{
   public static void main(String[] args)
   {
      Person p1 = new Person("孙悟空" , "12343433433");
      Person p2 = new Person("孙行者" , "12343433433");
      Person p3 = new Person("孙悟饭" , "99933433");
      // p1和p2的idStr相等,所以返回true
      System.out.println("p1和p2是否相等"
         + p1.equals(p2));
      // p2和p3的idStr相不等,所以返回false     
      System.out.println("p2和p3是否相等"
         + p2.equals(p3));
   }
}

注意:上面代码中判断obj是否是person类实例不能用obj instanceof Person来判断。因为对于 instanceof 而言,当前面对象是后面类的实例或其子类的实例都将返回true,所以重写equals方法判断两个对象是否是同一个类的实例时使用 instanceof 运算符是有问题的。

猜你喜欢

转载自blog.csdn.net/qq_43215734/article/details/85226935
今日推荐