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