您的位置:首页 > 移动开发 > Objective-C

Java Object 对象拷贝答疑

2016-07-12 16:41 417 查看

Java Object 对象拷贝答疑

@author ixenos

摘要:在对象的clone过程需要注意的几点、关于关键字this、super

关于clone[对象拷贝]

  在实际编程过程,有时候我们会遇到一种情况:当你有一个对象A,在某一个时刻,A已经保存了对应的属性值,而且这些值本身是有效的,这个时候可能需要一个和A完全相同的对象B,并且当B里面的属性值发生变化的时候,A中的属性值不受影响,可以理解为A和B独立,但是B的初始化不是按照我们平时创建该对象的时候的初始化操作,B的初始化数据完全来自A。

  对Java存储模型了解的人都明白,在Java里面如果针对两个对象引用采取赋值操作的时候,仅仅是让两个引用指向了同一对象(即值传递,并非引用传递),如果其中一个引用里面的对象属性改变的时候会影响另外一个对象属性跟着改变,所以Java语言本身的对象赋值语句是不能完成上边的需求的。在这种时候,就需要用到Object类里面的通用方法clone(),这里需要说明的是:

  通过clone()方法创建的对象是一个新对象,它可以认为是源对象的一个拷贝,但是在内存堆中,JVM会为这个拷贝分配新的对象存储空间来存放该对象的所有状态。该拷贝和普通对象使用new操作符创建的对象唯一的区别在于初始值,这个拷贝的初始值不是对象里面成员的默认值,而是和源对象此刻状态的成员的值是一样的

  下边这段代码是clone方法的运用:

class AClass{
public AClass(int a){
System.out.println("A Init "+ a);
}

public void fun(int a){
System.out.println("fun int "+a);
}

}
class BClass extends AClass{
private int a = 24;

private static int b = 11;

public BClass(){
this(12);

//this.b = 12;

super.fun(12);

}
public BClass(int a)

{
super(12);

System.out.println("B init " + this.a);

}

}


View Code

  针对以上代码段做几个详细的说明:

  super.fun(12):在子类中访问父类的成员的时候使用super关键字,但是super不能访问父类的private成员;

  super(12):子类如果要调用父类的构造函数,可以直接使用super(param)这中调用方式,但是如果是调用父类的构造方法,是不能够在子类的其他函数块里面进行的,只能在构造函数中进行,而且一般不能和this(param)同时出现,关于它们在构造函数中的使用,将在小节7中介绍;

  //this.b=12:虽然这句话注释掉了,但是这句话是可以通过JVM编译的,这里需要区分的是在static块中调用非static成员和在普通块中调用static成员,在普通语句中调用static成员是可以使用this.VAR的方式进行操作的,但是一般不提倡这样做,因为一般调用static成员在编程的时候都是使用独一无二的方式Class.VAR,而不使用this.VAR。

  this(12)/this.a:this在调用自己的成员的构造函数的时候,直接使用this(param)方式调用构造函数,如果是调用普通的成员就使用后者。

  *:this和super都不能放在static块中运行,不论是static的静态初始化块,还是static的静态方法块,里面都不能出现this和super的关键字,这个道理很简单:static块是Class域的,就是说static块里面的内容是在JVM的类加载器第一次加载类的时候就被初始化了,而且整个过程只会初始化一次。而this和super都是Object域的操作,this指代的是实例本身,而不是类,同样的super指代的是父类的实例本身,也不是类,所以this和super是不能够出现在static的静态方法块里面的。其实从概念上讲,static和this、super操作的对象不一样,static是属于Class的,而super和this是属于Object的,所以编程过程必须注意这点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: