谈谈 Object 类
2016-03-18 16:04
447 查看
clone() 方法
Java 中并没有指针的概念,许多程序员往往会忽略对象与引用的区别。Java 不能通过简单的赋值来解决对象复制的问题,常用 clone() 方法来复制对象。比如函数参数类型是自定义的类时,此时便是引用传递而不是值传递。
请看如下代码:
// 测试代码: A a1=new A(); A a2=new A(); a1.name="a1"; a2=a1; a2.name="a2"; System.out.println("a1.name="+a1.name); System.out.println("a2.name="+a2.name); // 输出结果: a1.name=a2 a2.name=a2
其实 al 和 a2 指向同一块内存地址,修改一个必然会影响到另一个。如果希望修改 a1 不影响到 a2 的话,可以使用 clone() 方法。
使用 clone() 方法要求如下:
1. 必须实现 Cloneable 接口(为什么呢?该接口是空的,可以看做是一个规定,如果不实现该接口,就会报 ClassNotSupported 异常。类似的还有 Serializable 接口)
2. 必须重载 clone() 方法,使用 super.clone() 调用 Object 类的 clone() 方法。
// 测试代码 public class A implements Cloneable{ public String name; public Object clone() { A obj = null; try{ obj =(A)super.clone(); }catch(CloneNotSupportedException e){ e.printStackTrace(); } return obj; } } public class ObjectTest { @Test public void testClone(){ A a1 = new A(); a1.name= "a1"; A a2 = (A)a1.clone(); a2.name = "a2"; System.out.println("a1.name="+a1.name); System.out.println("a2.name="+a2.name); } } // 输出结果: a1.name=a1 a2.name=a2
由输出结果可以看出,当 Class A 的成员变量类型都为基本类型的时候,只要如上面进行简单的 clone() 就可以了(称为影子克隆)。
但是如果 Class A 的成员变量类型包括非基本类型的话,请看下面例子:
// 测试代码 public class A implements Cloneable { public String[] name; public A() { name = new String[2]; name[0] = "xx"; name[1] = "yy"; } public Object clone() { A obj = null; try { obj = (A) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } } public class ObjectTest { @Test public void testClone(){ A a1 = new A(); A a2 = (A)a1.clone(); a2.name[1]="zz"; System.out.println("a1.name="+a1.name); System.out.println("a1.name="+a1.name[0]+a1.name[1]); System.out.println("a2.name="+a2.name); System.out.println("a2.name="+a2.name[0]+a2.name[1]); } } // 输出结果: a1.name=[Ljava.lang.String;@16352be6 a1.name=xxzz a1.list.size=2 a2.name=[Ljava.lang.String;@16352be6 a2.name=xxzz a2.list.size=2由此看出,如果类中有复杂的成员变量,影子克隆已经达不到效果,因为两个对象的成员变量指向的地址还是一样的,这时候就需要使用深度 clone,成员变量也需要进行 clone。
// 代码 public class A implements Cloneable { public String[] name; public A() { name = new String[2]; name[0] = "xx"; name[1] = "yy"; } public Object clone() { A obj = null; try { obj = (A) super.clone(); obj.name = (String[])name.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } } public class ObjectTest { @Test public void testClone(){ A a1 = new A(); A a2 = (A)a1.clone(); a2.name[1]="zz"; System.out.println("a1.name="+a1.name); System.out.println("a1.name="+a1.name[0]+a1.name[1]); System.out.println("a2.name="+a2.name); System.out.println("a2.name="+a2.name[0]+a2.name[1]); } } // 输出 a1.name=[Ljava.lang.String;@3cbdcccc a1.name=xxyy a2.name=[Ljava.lang.String;@50d0843b a2.name=xxzz
类复制成功,且 al 和 a2 之间不会相互影响。clone() 方法的分析到此结束。
int hashCode() 方法
返回该对象的哈希码值(是一串数字 int 类型)。如果有必要,子类要对这个方法进行重写,让子类和父类的 hashcode() 返回值不一样。
两个对象不相等,那么这两个对象的 hashcode() 返回值可能不一样,但是程序员应该意识到,为不相等的对象产生不同整数结果可以提高哈希表性能。
equals() 方法
如果重写了 equals 方法,则必须重写 hashCode() 方法。因为如果 equals 返回 true,hashCode() 返回值必须是相同值。相关文章推荐
- iOS安全攻防(二十三):Objective-C代码混淆
- Objective-C动态创建类(ARC版)
- object_setInstanceVariable is unavailable: not available in automatic reference counting mode
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- Net.Sf.Json java Object to JsonObject
- unittest 'module' object has no attribute 'TestCase'--自己坑自己
- aix中使用xlc编译生成动态链接库(shared object)(.so)文件的方法
- jsp和maven和object-c的关联
- jquery和com和object-c的关联
- jetty启动时 java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor
- ArrayList中add(Object obj)方法的注意事项
- Swift比Objective-C有什么优势?
- Swift和Objective-C的联系
- Objective-C是动态运行时语言是什么意思?
- org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
- COM 学习
- 复合语句在 Objective-C 中的使用
- Object 转 json 工具类
- Objective-C中谓词(NSPredicate)的应用
- Object对象之equals方法