Object类中四个常需要重写的方法
public class Object
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。 java.lang.Object
_______________________________________________
hashCode 的常规协定是:
* 在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
* 如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:
此对象的一个哈希码值。
_______________________________________________
equals()方法是在Object类中定义的方法,它的声明格式为:
public boolean equals(Object obj)
指示某个其他对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:
* 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
* 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
* 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
* 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
* 对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
操作符"=="两边操作元可以简单类型也可是引用类型,当两边都是简单类型时,比较的是栈里面的值(value),当两边是引用类型时,比较的是两个引用类型变量
保存的地址,即两个引用变量都引用同一个对象,结果才为true.
(注意:"=="可以用于数组类型)
当创建的两个引用类型对象objec1,object2有相同的属性时,可以重写equals()方法,使 objec1.equals(object2) 的结果为true.
public class Person { //写一个Person类
private int id;
private String name;
public int hashCode() { //重写哈希码以维护 hashCode 方法的常规协定,相等对象必须具有相等的哈希码。
int temp = 23; //写一个随意的变量作为类标识
return temp+this.id*43; //防止子类哈希码的重复
}
//重写一个equals()方法,当Person类型对象有相同的id时返回true
public boolean equals(Object otherobject) { //指示某个其他对象是否与此对象otherobject“相等”
if(this==otherobject) //自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true
return true;
if(otherobject==null) //对于任何非空引用值 x,x.equals(null) 都应返回 false
return false;
if(getClass().getName() != otherobject.getClass().getName()) //必须是相同引用类型对象间比较
return false;
if(!(otherobject instanceof Person)) //判断otherobject是否是Person类型
return false;
Person other = (Person)otherobject; //多态还原
return id == other.id; //id相等返回true,否则返回false
}
public String toString() {
return getId()+": "+getName();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**这个似乎重写也可以的,但是逻辑不强
*public boolean equals(Object obj){
* if(obj == null){
* return false;
* }else if(obj instanceof Person){ //判断obj是否是Person类型
* Person s1 = (Person)obj; //多态还原
* return this.id == s1.getId();
* }else{
* return false;
* }
* }
*/
注意:当equals()方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
_______________________________________________
clone
protected Object clone()
throws CloneNotSupportedException
创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。一般来说,对于任何对象 x,如果表达式:
x.clone() != x
是正确的,则表达式:
x.clone().getClass() == x.getClass()
将为 true,但这些不是绝对条件。一般情况下是:
x.clone().equals(x)
将为 true,但这不是绝对条件。
按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,则 x.clone().getClass() == x.getClass()。
按照惯例,此方法返回的对象应该独立于该对象(正被克隆的对象)。要获得此独立性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被克隆对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。
Object 类的 clone 方法执行特定的克隆操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。注意:所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我克隆。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。
Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。
返回:
此实例的一个克隆。
抛出:
CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法克隆某个实例。
_______________________________________________
toString
public String toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
该对象的字符串表示形式。
例子:
public class TestClone implements Cloneable{ //类可以被clone
private int temp = 0;
private String name = new String("**copy**");
//浅clone不需要重写,深clone需要重写
public static void main(String[] args) throws Exception{
TestClone tc = new TestClone();
TestClone o = (TestClone)tc.clone();
System.out.println(tc == o);//clone对象和源对象比较
System.out.println(tc.name==o.name);
//浅拷贝原样复制,拷贝出来的对象仍然指向源对象的value
}
}
//写类:必须写无参构造器,一般要求对epuals和hashCode方法重写,
//再者就是重写clone方法 |