JAVA源码分析之---Object类(二)---hashCode,equals,clone方法的使用
2016-07-11 07:35
1036 查看
今天咱们剖析hashCode(),equals(),clone()方法的使用
咱们继续第3个方法:
这个方法native修饰,java本身不实现,由c/c++来实现,具体根据所依赖的平台来。
这个方法返回该对象的哈希代码值,在java里,专门有一个类是java.util.HashMap,这个值根据哈希表来的。
如果在java程序中,对同一个对象多次调用,这个对象的哈希值也不会变,可以理解为给每一个对象上了个标记,这个标记是始终不会变的。所以可以用来比较两个对象是否是同一个对象,比如有A和B"两"个对象,如果这"两"个对象的哈希值一样,那么其实是一个对象,稍后在equals方法中,会有体现。
但是,如果在两个程序中,对象的哈希值可以不一样。可以这样认为,在一个程序中,生成的一个对象会拥有一个哈希值,如果在本程序中,这个哈希值唯一。但是如果脱离了本程序,这个哈希值可以不一样。
同理,如果是判断两个对象是否相等,如果相等,那么每个调用的方法必定会产生同一个哈希值。
举例:
a的HashCode值51,b的HashCode值51。
这里a和b都指向了同一个对象,hash值是一样的。
第4个方法:equals方法
这个方法具有自我性,对称型,传递性,一致性。
自我性体现在:如果x.equals(x),那么在x不为空的前提下,那么返回true,否则抛出NullPointorException。
对称型体现在:如果x和y相等,那么y和x也相等。
传递性体现在:如果x==y,y==z,那么x==z。
一致性体现在:如果x==y为true,那么只要不修改,后面无论调用多少次,一致为true。
而且特别要注意的一点是:一个非空对象和null值比较,那么一定返回false。
如果要对equals方法进行overide重写,那么一定要保证相同对象拥有同样的hash值。
举例:
结果:
第5个方法:clone() 克隆方法
native修饰,java本身不实现。
clone()方法是创建并返回该对象的一个副本,注意,创建后,就是两个对象,和引用同一个对象不一样。也就是说:x.clone() !
= x为true。
一般情况下,x.clone().getClass() =
= x.getClass()为true,x.clone().equals(x)也为真。
如果在对一个对象希望拥有它的全部属性,并且又能随时修改,但同时又不会影响原有的对象,可以使用clone方法,有点类似于SVN的分支。
而且:如果想要对一个对象进行clone,必须实现Cloneable接口,而且要重写clone方法,否则会报CloneNotSupportedException异常。
举例:写一个实体类TestClone
最终结果:
咱们继续第3个方法:
public native int hashCode();
这个方法native修饰,java本身不实现,由c/c++来实现,具体根据所依赖的平台来。
这个方法返回该对象的哈希代码值,在java里,专门有一个类是java.util.HashMap,这个值根据哈希表来的。
如果在java程序中,对同一个对象多次调用,这个对象的哈希值也不会变,可以理解为给每一个对象上了个标记,这个标记是始终不会变的。所以可以用来比较两个对象是否是同一个对象,比如有A和B"两"个对象,如果这"两"个对象的哈希值一样,那么其实是一个对象,稍后在equals方法中,会有体现。
但是,如果在两个程序中,对象的哈希值可以不一样。可以这样认为,在一个程序中,生成的一个对象会拥有一个哈希值,如果在本程序中,这个哈希值唯一。但是如果脱离了本程序,这个哈希值可以不一样。
同理,如果是判断两个对象是否相等,如果相等,那么每个调用的方法必定会产生同一个哈希值。
举例:
package edu.java.test; public class TestHashCode01 { /** * 测试两个引用指向同一个对象的哈希值 * @param args */ public static void main(String[] args) { String a = "3"; String b = a; System.out.println("a的HashCode值" + a.hashCode()); System.out.println("b的HashCode值" + b.hashCode()); } }这里的测试结果为:
a的HashCode值51,b的HashCode值51。
这里a和b都指向了同一个对象,hash值是一样的。
第4个方法:equals方法
public boolean equals(Object obj) { return (this == obj); }这个方法返回一个boolean类型。该方法主要是比较两个对象是否是同一个。而比较的不是对象本身,而是对非NULL对象的引用。
这个方法具有自我性,对称型,传递性,一致性。
自我性体现在:如果x.equals(x),那么在x不为空的前提下,那么返回true,否则抛出NullPointorException。
对称型体现在:如果x和y相等,那么y和x也相等。
传递性体现在:如果x==y,y==z,那么x==z。
一致性体现在:如果x==y为true,那么只要不修改,后面无论调用多少次,一致为true。
而且特别要注意的一点是:一个非空对象和null值比较,那么一定返回false。
如果要对equals方法进行overide重写,那么一定要保证相同对象拥有同样的hash值。
举例:
package edu.java.test; import java.util.Date; public class TestHashCode02 { /** * 测试两个引用同一个对象的变量是否相等 * @param args */ public static void main(String[] args) { Date date = new Date(); Date date2 = date; System.out.println("date的hashCode = "+date.hashCode()); System.out.println("date2的hashCode = "+date2.hashCode()); System.out.println("date == date2 4000 的值 = " + date.equals(date2)); } }
结果:
date的hashCode = -452137556 date2的hashCode = -452137556 date == date2 的值 = true
第5个方法:clone() 克隆方法
protected native Object clone() throws CloneNotSupportedException;
native修饰,java本身不实现。
clone()方法是创建并返回该对象的一个副本,注意,创建后,就是两个对象,和引用同一个对象不一样。也就是说:x.clone() !
= x为true。
一般情况下,x.clone().getClass() =
= x.getClass()为true,x.clone().equals(x)也为真。
如果在对一个对象希望拥有它的全部属性,并且又能随时修改,但同时又不会影响原有的对象,可以使用clone方法,有点类似于SVN的分支。
而且:如果想要对一个对象进行clone,必须实现Cloneable接口,而且要重写clone方法,否则会报CloneNotSupportedException异常。
举例:写一个实体类TestClone
package edu.java.test; public class TestClone implements Cloneable { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }接着编写测试类:
package edu.java.test; public class TestClone02 { public static void main(String[] args) throws CloneNotSupportedException { TestClone tc = new TestClone(); tc.setAge("10"); TestClone clone = (TestClone) tc.clone(); System.out.println("tc的hashCode"+tc.hashCode()); System.out.println("clone的hashCode"+clone.hashCode()); System.out.println("tc的年龄 = " + tc.getAge()); System.out.println("tc的clone的年龄 = " + clone.getAge()); System.out.println(clone == tc); System.out.println(clone.equals(tc)); System.out.println(tc.getClass() + ":" + clone.getClass()); } }
最终结果:
tc的hashCode14927396 clone的hashCode31817359 tc的年龄 = 10 tc的clone的年龄 = 10 false false class edu.java.test.TestClone:class edu.java.test.TestClone
相关文章推荐
- Objective-C -------简单版的摇一摇
- List<Map<String,Object>>的取值与赋值
- R-FCN: Object Detection via Region-based Fully Convolutional Networks
- 《OpenGL ES 2.0 Programming Guide》第12章“Framebuffer Objects”示例代码【C语言版】
- iOS学习(二十八)Objective-C 代理设计模式
- Objective-C :Category
- Java中Object对象的hashCode方法和String对象的hashCode
- iOS学习(二十七)Objective-C 协议
- iOS学习(二十六)Objective-C 分类
- Objective-C 构造方法
- Objective C转Swift注意事项(一)合理使用结构体,枚举,extensions
- iOS学习(二十五)Objective-C 动态创建
- iOS学习(二十四)Objective-C 动态绑定
- iOS学习(二十三)Objective-C 静态vs动态
- 泛型/dynamic/object作用
- Three.js源码之Object3D
- #码神心得_09# 包装类、Object类方法、final、抽象类
- Object方法详解
- R-CNN: Rich feature hierarchies for accurate object detection and semantic segmentation
- iOS学习(二十二)Objective-C 动态识别的应用