Object为何声明clone()?

代码导航 毕业设计 1

既然实现Cloneable必须重写clone(),调用clone()必须实现Cloneable,为何不直接在Cloneable里声明clone()?

回复

共2条回复 我来回复
  • 毕设助手
    这个人很懒,什么都没有留下~
    评论

    Object.clone实现的是浅拷贝,调用clone之后,jvm会检查你是否是继承了Cloneable接口,没有的话直接报错了,有的话申请一块和你的对象一抹一样的大小的内存,然后浅拷贝。

    JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
    JVMWrapper("JVM_Clone");
    Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
    const KlassHandle klass (THREAD, obj->klass());
    JvmtiVMObjectAllocEventCollector oam;if (!klass->is_cloneable()) {
    ResourceMark rm(THREAD);
    //errorerror
    }// Make shallow object copy
    const int size = obj->size();
    oop new_obj_oop = NULL;
    if (obj->is_array()) {
    const int length = ((arrayOop)obj())->length();
    new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
    } else {
    new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
    }Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop,(size_t)align_object_size(size) / HeapWordsPerLong);
    // Clear the header
    new_obj_oop->init_mark();BarrierSet* bs = Universe::heap()->barrier_set();
    bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));Handle new_obj(THREAD, new_obj_oop);
    if (java_lang_invoke_MemberName::is_instance(new_obj()) && java_lang_invoke_MemberName::is_method(new_obj())) {
    Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj());
    if (method != NULL) {
    methodHandle m(THREAD, method);
    m->method_holder()->add_member_name(new_obj());
    }
    }
    if (klass->has_finalizer()) {
    new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
    new_obj = Handle(THREAD, new_obj_oop);
    }
    return JNIHandles::make_local(env, new_obj());
    }
    }
    
    0条评论
  • 毕设工坊
    这个人很懒,什么都没有留下~
    评论

    clone和其他方法不一样,是个naive方法,必须有特殊的实现,有一部分必须交给底层去做。

    手用调用new是无法完全代替clone的。派生类是无法访问基类private变量的,那么即使两个类都实现了Cloneable,派生类也无法做到复制基类private变量,这种情况下调用super.clone也只能得到一个新的基类对象,对派生类的克隆对象没有帮助。

    所以java这里做了特殊处理,派生类的clone必须调用基类的clone,这样程序就会从object开始调用clone,object的clone会让jvm创建一个同样类型的对象,然后从上到下依次调用clone来对同一个对象的各变量进行赋值,最终得到一个变量完全相等的对象

    0条评论

发表回复

登录后才能评论