转载请注明出处,谢谢!

protected 域(或方法)微妙的规则

protected 域(或方法)对本包内的所有类可见(当然包括子类),那么,子类可以获得访超类受保护域(或方法)的权利,但是,若子类和超类不在同一个包下,就不能访问超类对象的这个受保护域(或方法)。也就是说,不在一个包下,子类中不能通过一个父类对象的引用来获得父类受保护的域(或方法),测试如下。

  1. package protect2;
  2. public class P{
  3. protected int a;
  4. public P(){}
  5. public P(int a){
  6. this.a = a;
  7. }
  8. protected void fun(){
  9. System.out.println("父类protected方法");
  10. }
  11. }
  1. package protect2;
  2. public class ProtectedTest {
  3. public String s;
  4. public ProtectedTest(String s) {
  5. this.s = s;
  6. }
  7. P ap = new P(10);
  8. void foo() {
  9. ap.fun();
  10. System.out.println("ap.a " + ap.a);
  11. }
  12. public static void main(String[] args) {
  13. ProtectedTest test = new ProtectedTest("abcdef");
  14. test.foo();
  15. System.out.println(test.s);
  16. }
  17. }
  1. package protect;
  2. import protect2.P;
  3. class C extends P{
  4. public int b;
  5. public C(int a,int b){
  6. super(a);
  7. this.b = b;
  8. }
  9. public void afun(){
  10. P pp = new P(10);
  11. System.out.println("C.a= " + a);
  12. System.out.println("P.a= " + pp.a);//ERROR:The field P.a is not visible
  13. pp.fun(); //ERROR:The method fun() from the type P is not visible
  14. }

浅拷贝与深拷贝

Object类对自己的具体子类的域一无所知,Object类的clone方法只是将各个域进行拷贝。数值或基本类型不会出现问题,但是,如果在对象中包含了引用对象,这些对象的内容没有被自我复制,拷贝的结果也即是原始对象和拷贝对象引用着同一个引用对象(一般地,动词“引用”可理解为“管理”,就是指向同一内存)。

浅拷贝满足:

  1. x.clone() != xtrue
  2. x.clone().getClass() == x.getClass()true
  3. ((x.clone().field1 ) == (x. field1))&& … &&((x.clone().fieldN )==(x. fieldN))也为 true

如果原始对象与浅拷贝对象共同引用(管理、指向)的引用对象是不可变的,将不会产生任何问题,如,引用对象是String类对象;或引用对象在其生命周期不会发生变化,具体来说,管理它的类中没有更改它的方法,也没有返回对它引用的方法(分享其管理权的方法)。

如果原始对象管理的引用对象是可变的,就必须需重新定义clone方法,来实现深层次的拷贝。要对涉及的每一个类,判断以下两点:

  • 默认的clone方法是否满足需求。
  • 默认的clone方法是否能通过调用可变引用对象的clone方法得到解决。

对涉及的每一个类,深拷贝要满足:

  1. x.clone() != xtrue
  2. x.clone().getClass() == x.getClass()true
  3. x.clone().equals(x)也为 true ,当然equals方法是如此重写过的

Object类中的clone方法被声明为protected,防止出现文章开头所提到的,子类和超类不在同一个包下的情况,要声明clonepublic,来实现深拷贝:

  1. import java.util.Date;
  2. public class EqualsT {
  3. public static void main(String[] args) throws CloneNotSupportedException {
  4. Date hireDay = new Date();
  5. Employee e1 = new Employee("Tommy", 10, "9998", hireDay);
  6. Employee e2 = new Employee("Tommy", 10, "9998", hireDay);
  7. System.out.println(e1.equals(e2));
  8. System.out.println(e1 == e2);
  9. Employee e3 = (Employee) e1.clone();
  10. System.out.println(e1.equals(e3));
  11. }
  12. }
  13. //Cloneable为标记接口,接口内没有方法。
  14. class Employee implements Cloneable {
  15. String name;
  16. int age;
  17. String salary;
  18. Date hireDay;
  19. public Employee(String name, int age, String salary, Date hireDay) {
  20. super();
  21. this.name = name;
  22. this.age = age;
  23. this.salary = salary;
  24. this.hireDay = hireDay;
  25. }
  26. @Override
  27. public boolean equals(Object otherObject) {
  28. if (this == otherObject)
  29. return true;
  30. if (otherObject == null)
  31. return false;
  32. if (!(otherObject instanceof Employee))
  33. return false;
  34. Employee other = (Employee) otherObject;
  35. return name.equals(other.name) && age == other.age && salary.equals(other.salary)
  36. && hireDay.equals(other.hireDay);
  37. }
  38. @Override
  39. protected Object clone() throws CloneNotSupportedException {
  40. // call Object.clone()
  41. Employee cloned = (Employee) super.clone();
  42. // call mutable fields
  43. cloned.hireDay = (Date) hireDay.clone();
  44. return cloned;
  45. }
  46. }
  47. Output
  48. true
  49. false
  50. true

  1. // JDK中Date类的克隆方法
  2. public Object clone() {
  3. Date d = null;
  4. try {
  5. d = (Date)super.clone();
  6. if (cdate != null) {
  7. d.cdate = (BaseCalendar.Date) cdate.clone();
  8. }
  9. } catch (CloneNotSupportedException e) {} // Won't happen
  10. return d;
  11. }

——@guoyangde http://www.cnblogs.com/LittleTreasureBox/p/8904016.html

JAVA如何实现深拷贝的更多相关文章

  1. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  2. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  3. 内功心法 -- Java中的深拷贝和浅拷贝

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...

  4. 浅析Java中的深拷贝和浅拷

      浅析Java中的深拷贝和浅拷贝 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: in ...

  5. Java 浅拷贝、深拷贝,你知多少?

    这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...

  6. 2种方法实现java对象的深拷贝

    2种方法实现java对象的深拷贝 2017年12月03日 22:23:07 iCoding91 阅读数 4420更多 分类专栏: java   版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...

  7. Java中的深拷贝和浅拷贝

    1.浅拷贝与深拷贝概念 (1)浅拷贝(浅克隆) 浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源 ...

  8. Java 浅拷贝和深拷贝的理解和实现方式

    Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...

  9. java克隆之深拷贝与浅拷贝

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java深拷贝与浅拷贝实际项目中用的不多,但是对于理解Java中值传递,引用传递十分重要,同时个人认为对于理解内存模型也有帮助,况且面试中也是经常问 ...

随机推荐

  1. poj-1028 -网页导航

    Description Standard web browsers contain features to move backward and forward among the pages rece ...

  2. Android_scaleType属性

    这里我们重点理解ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType).android:scaleType ...

  3. 【Saltstack】Saltstack简单说明

    [Saltstack] Saltstack是一个服务器集中管理中心平台,可以帮助管理员轻松的对若干台服务器进行统一操作.类似的工具还有Ansible,Puppet,func等等.相比于这些工具,sal ...

  4. Android 源代码结构

    简介 在使用Andriod SDK进行应用程序开发的时候,我们需要对源代码进行调试,有可能需要进入到某个Android API函数内部进行跟踪调试.但是,如果目标版本的SDK没有关联对应版本的源代码的 ...

  5. va_list va_start va_end va_arg 解决变参问题

    解决参数个数不确定的问题. 头文件 #include<stdarg.h> VA_LIST 是在C语言中解决变参问题的一组宏,用于获取不确定个数的参数. #ifdef _M_ALPHA ty ...

  6. Python中的unittest和logging

    今天使用Python的unittest模块写了些单元测试,现记录下要点: 使用unittest的基本格式如下: import unittest class Test(unittest.TestCase ...

  7. Flume日志采集系统

    1.简介 Flume是Cloudera提供的一个高可用.高可靠.分布式的海量日志采集.聚合和传输的系统. Flume支持在日志系统中定制各类数据发送方用于收集数据,同时Flume提供对数据进行简单的处 ...

  8. 用js来实现那些数据结构(数组篇01)

    在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念.那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记 ...

  9. 【iOS】单元测试

    iOS单元测试(作用及入门提升) 字数1704 阅读16369 评论26 喜欢247 由于只是一些简单实用的东西,学学还是挺不错的.其实单元测试用的好,开发起来也会快很多.单元测试对于我目前来说,就是 ...

  10. exports

    暴露函数 var bar = require("./bar.js"); var msg = "你好"; var info = "呵呵"; f ...