`
niwtsew
  • 浏览: 71927 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Why clone() is protected rather than public,it's a bug

阅读更多

 Why clone() is protected rather than public ?

一直以来不明白,网上给的解释貌似也不合理,看到sun的bug repository上的一个帖子,感觉这是sun的一个bug,参见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4098033

Bug ID: 4098033
Votes 25
Synopsis Cloneable doesn't define .clone
Category java:classes_lang
Reported Against 1.1.4 , 1.1.5 , 1.2beta2 , kestrel-rc1
Release Fixed
State 11-Closed, Will Not Fix, request for enhancement
Priority: 4-Low
Related Bugs 4103477
Submit Date 09-DEC-1997
Description
Cloneable doesn't define clone. This means that programmers cannot
polymorphically clone objects, such as in:

for (int i = 0; i < myVector.size(); i++) {
result.myVector.setElementAt(
((Cloneable) myVector.elementAt()).clone(), i);
}

Secondly, programmers have no idea whether clones are deep or shallow.

Since interfaces cannot be changed, suggested solution:
add an interface for deep clones:

public interface interface Copyable {
public Object clone(); // guarantees deep clone
}
xxxxx@xxxxx 11/3/04 21:17 GMT
Work Around



======================================================================




Get the Class object, examine the interfaces it implements to see if
it implements Cloneable(), if so do a dynamic method call on the
clone() method....
(Review ID: 102333)
======================================================================

xxxxx@xxxxx 2000-03-13

Oh, yes, this is certainly possible. It is *really*, ugly.
So it should be documented as a workaround, but it should not deter
us from fixing the problem. This is in the "workaround as painful
as needles under your fingernails" realm.
Evaluation Cloneable doesn't define a public clone() operation, making it practically
useless. For obvious reasons, we'll never be able to add a public clone
operation to Cloneable, but we will be able to make a new interface that
extends Cloneable and does what Cloneable should have done. What to call this
new interface is open to debate (Clonable? Copyable? Herbert?)

At any rate, I believe that this should definitely be implemented in the
next major release after 1.2.


xxxxx@xxxxx 1998-04-28

========================================================================

You know, I just thought of something. The "obvious" reason we can't
add clone() to Cloneable is that adding new methods to interfaces is
an incompatible change. The reason adding new methods is incompatible
is that is makes concrete classes suddenly abstract.

But in this case that wouldn't happen -- existing classes *all* have
a clone method. No such class would be abstract. This may be an
exception to the incompatible change-ness of adding methods to interfaces.
We at least ought to consider this, because if we *can* add it to
Cloneable it fixes a problem with existing systems, whereas if we add
a new interface we only fix new code written by highly-informed people.

The downside I see is that we will public-ify the clone method of any
existing class that both implements Cloneable but doesn't declare clone
as public. I have always found it hard to imagine the value of such
a thing, and so I doubt this is a serious issue in deep principle. But
others may disagree.

In any case, this is clearly the ideal fix, and our instincts that it
isn't possible are probably wrong.

xxxxx@xxxxx 2000-02-28:

Unfortunately, this does not work; the clone method in Object is protected, not public. All methods in interfaces are inherently public. Thus, a class that currently implements Cloneable but has no public clone method would break. In practice, I doubt that there are many such classes out there, but there are almost certainly a few.

It is worth noting that adding methods to interfaces breaks source compatibility, and not binary compatibility. In this instance, we might consider intentionally breaking source compatibility, knowing that the odds of a problem are low.

xxxxx@xxxxx 2000-02-28

Ah, yes, if I inherit a public method from an interface that is satisified
by an inherited method of the same signature from my superclass, but with
more restricted access, I must redeclare the more restricted access method
that statisfies it as public -- it is not made public by inference. I had
forgotten that point, and so assumed that the protected method would be
made public by virtue of inheriting a public method of the same signature.
Sigh, at least in this case. It could have solved it so much nicer.

xxxxx@xxxxx 2000-02-29

Sun's Technical Review Committee (TRC) considered this issue at length
and recommended against taking any action other than improving the documentation
of the current Cloneable interface. Here is the full text of the recommendation:

The existing Java object cloning APIs are problematic. There is
a protected "clone" method on java.lang.Object and there is an
interface java.lang.Cloneable. The intention is that if a class
wants to allow other people to clone it, then it should support
the Cloneable interface and override the default protected clone
method with a public clone method. Unfortunately, for reasons
conveniently lost in the mists of time, the Cloneable interface
does not define a clone method.

This combination results in a fair amount of confusion. Some
classes claim to support Cloneable, but accidentally forget to
support the clone method. Developers are confused about how
Cloneable is supposed to work and what clone is supposed to do.

Unfortunately, adding a "clone" method to Cloneable would be
an incompatible change. It won't break binary compatibility,
but it will break source compatibility. Anecdotal evidence
suggests that in practice there are a number of cases where
classes support the Cloneable interface but fail to provide
a public clone method. After discussion, TRC unanimously
recommended that we should NOT modify the existing Cloneable
interface, because of the compatibility impact.

An alternative proposal was to add a new interface
java.lang.PubliclyCloneable to reflect the original intended
purpose of Cloneable. By a 5 to 2 majority, TRC recommended
against this. The main concern was that this would add yet
more confusion (including spelling confusion!) to an already
confused picture.

TRC unanimously recommended that we should add additional
documentation to the existing Cloneable interface to better
describe how it is intended to be used and to describe "best
practices" for implementors.

xxxxx@xxxxx 2000-07-14


A new SR opened for this report suggests that only classes
failing to support the contract of Cloneable would encounter
a source incompatibility. This is incorrect. A Cloneable class
with a protected (not public) clone method would be faithfully
honoring its contract, but would no longer compile.
.
xxxxx@xxxxx 11/3/04 21:42 GMT
Comments   
  Include a link with my name & email   

Submitted On 12-JAN-1998
sschell I agree that the Cloneable interface should define
the clone() method, it doesn't make a whole lot of
sense otherwise. Also, can anyone answer the question:
Why don't all Objects have the ability to clone()
themselves? It seems odd that it's defined in
the Object class itself (protected), yet is not
available (public) to the rest of the classes.
I'd be happy to hear comments why this particular
method is not public in java.lang.Object for I
believe it could be very useful.
Scott Schell
Member Technical Staff
Lucent Technologies, Inc.
Database Technologies
11900 Pecos St. RM2H-35
Westminster, CO 80234
(303) 538-4954
saschell@lucent.com


Submitted On 27-AUG-1998
jgeist I agree that this is a problem. Object should
define a public clone() method. If it did, would
there even be a need for a Cloneable interface?
Currently, there is no way to write code capable
of copying classes that can handle both ordinary
classes and wrapper classes(i.e., java.lang.String,
java.lang.Integer, etc...). For example, suppose
I want to write a program that uses ObjectStreams
to send objects over a Socket. Because of a weird
feature (BUG) in the ObjectStream code (see bug
#4065324), I must copy each Object before I send it
over the stream. This means I need to write extra
code to handle Strings, Points, Rectangles, etc...,
because they the only way to copy them is to call
a constructor (i.e., &quot;new String(blah)&quot;, where blah
is the string I want to send). I would much rather
be able to use a clone() method that is consistant
across all Objects, instead of testing each Object
to determine what class it is, and then using the
constructor for that class.
If anyone has any suggestions for a better
workaround, please email me.
Jonathan Geist
jgeist@cs.wright.edu


Submitted On 25-NOV-1998
Nexirius I have the same opinion as 'saschell'. The Object.clone() Method
should scan (using the reflection package) the class for attributes
and call their clone method (deep copy).
The same is true for the streamability interface.
A powerful language like Java should support a
basic functionality for persistence.


Submitted On 05-MAR-1999
kriff I'm perfectly satisfied with clone making shallow
copies. If deep-copies are desired, its a trivial
matter to implement clone() to do that.
My pet peeve with Cloneable is that
CloneNotSupportedException is a checked exception.
That means that you have to write a silly catch
block everytime you implement clone(). And what
happens if you inherit from a class that implements
Cloneable, but you want to prevent your class from
being cloned ? You usually can't throw
CloneNotSupportedException because the clone()
method you inherit doesn't contain a throws clause.
CloneNotSupportedException should extend
RuntimeException but I don't know if that change
can be made safely.
And make Object.clone() public and forget about
making a new interface. That change should be
perfectly safe.


Submitted On 08-JUN-1999
DougO You can get around this with reflection, but it's really slow:
obj.clone()
becomes:
obj.getClass().getMethod(&quot;clone&quot;, null).invoke(obj, null);
(catching all the appropriate exceptions, of course).
Not pretty, but it does work. My vote is for simply making Object.clone()
public-- this doesn't violate binary compatibility, does it?
As for shallow vs. deep copy, I think there ought to be two different methods,
because sometimes you really do want both, for the same class, e.g. Vector.
Please add something like deepClone() or deepCopy() to Object or Cloneable or
Herbert or whatever ends up being the real home of clone()...


Submitted On 04-DEC-2000
gberche As of JDK 1.3.0.1, the API documentation both for Cloneable
and for java.lang.Object.clone() has not been modified.
Until then this bug should be open, since the TRC decided
to do so. Please correct the API documentation and then
mark this bug as closed!



Submitted On 10-JAN-2001
gberche Serializable has even started being used to provide such polymorphic clone feature: see TomCat 3.1 's
StandardSessionManager.
It's a problem that needs fixing!


Submitted On 10-JAN-2001
gberche In addition, please also document more clearly that the preferred copy mechanism for the collections classes
is &quot;conventional copy&quot;
Set originalSet=...
Set copiedSet = new HashSet(originalSet);

Also please document better recommended ways to implement the clone() method
My understanding is that it should be something like
class MyClass {
[...]
public Object clone() {
MyClass copy = (MyClass) super.clone();
//for each field that need deep copy and that have defined
//the clone() method as part of their interface
copy.field = this.field.clone();
return copy;
}

This unintuitive API and the lack of documentation is really annoying!! Please fix!


Submitted On 15-MAY-2004
mikkotommila See bug 5045376 for a suggested alternative solution.

Submitted On 27-AUG-2009
May I ask why after twelve (!) years, this issue has still not been resolved? What can be so hard about adding a Copyable interface to the runtime library, as was suggested? This is really annoying because people are forced to use reflection where they shouldn't have to use it.


PLEASE NOTE: JDK6 is formerly known as Project Mustang

 

分享到:
评论

相关推荐

    Jlink V8固件升级提示Clone的解决方法!

    在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示!“the emulator is JLink-Clone, the segger software only support orginal segger device” 然后闪退,IDE崩溃关闭! 解决方案: 1....

    c++写的一个github快速下载器,clone速度可达10M/s

    c++写的一个github快速下载器,clone速度可达10M/s c++写的一个github快速下载器,clone速度可达10M/s c++写的一个github快速下载器,clone速度可达10M/s c++写的一个github快速下载器,clone速度可达10M/s c++...

    java Clone

    需要注意的是,`Object`类的`clone`方法是受保护的(protected),所以我们需要在覆盖的`clone`方法中将其暴露为公共的(public),以便外部类能够访问。 `clone`方法分为两种类型:浅克隆(Shadow Clone)和深克隆...

    MapReduce-based Assembly Clone Search for Reverse Engineering.pdf

    It is the first clone search engine that can efficiently identify the given query assembly function’s subgraph clones from a large assembly code repository. Kam1n0 is built upon the Apache Spark ...

    java clone的小例子

    protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; ...

    clone()示例源码

    通常,为了能够正确地克隆一个对象,你需要确保类的每个属性都是可克隆的,并且覆盖`Object`类中的`clone()`方法,声明为`protected`或`public`,因为默认它是`protected`的。 ```java public class MyClass ...

    java_clone用法

    对于一个对象`a`,`clone`方法会在堆上分配与`a`大小相同的内存空间,并将`a`的所有内容复制到这块新内存中。这包括原始类型的数据和引用类型的引用地址。然而,这种方式通常被称为“浅拷贝”。 #### 五、浅拷贝与...

    jlink v9 warning clone解决

    `jlink v9 warning clone`问题通常涉及到JLink版本9在与MDK配合使用时遇到的警告,提示可能与克隆设备或非法设备相关。 标题中的"jlink v9 warning clone解决"意味着开发者正在尝试解决关于JLink v9版本出现的克隆...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    A decent rule of thumb is to not inline a function if it is more than 10 lines long. Beware of destructors, which are often longer than they appear because of implicit member- and base-destructor ...

    2018-real-clone2-10.8s.rar

    在这个实战项目中,"2018-real-clone2-10.8s.rar"可能是该活动中某个挑战或比赛的成果,其目标可能涉及快速克隆或模拟某种行为或系统,而10.8s可能指的是完成任务所需的时间。 文件名"2018-real-clone2-training_...

    java clone

    1. 注意权限:默认情况下,`clone`方法是`protected`的,这意味着在同一个包内的类才能直接调用。如果需要在不同包的类中使用`clone`,需要将它声明为`public`。 2. 避免空指针异常:在覆盖`clone`方法时,确保检查...

    C#中Clone一个对象的值到另一个对象案例 c#经典案例.pdf

    A t2 = t1.Clone() as A; Console.WriteLine(t1.i + " " + t2.i); Console.WriteLine(t1.str + " " + t2.str); Console.WriteLine(t1.ins.bi + " " + t2.ins.bi); t2.i = 2; t2.str = "str2"; t2.ins.bi = ...

    Java Clone(类的复制)实例代码

    在Java编程语言中,`Clone`机制是一种对象复制的方式,允许创建一个现有对象的副本。在Java中,对象的默认复制是浅复制(shallow copy),这意味着只复制对象本身,而不复制它引用的对象。要实现深复制(deep copy)...

    JLinkV8/V9/OB固件可用新驱动7.65a等完美调试解决j-link is defective,j-link clone

    终于是搞好了几个固件都可以自动升级,可以用官网最新版驱动7.64b、7.65a等等,完美运行完美调试 使用方法:LINK-V8/ JLINK-OB刷入固件,(jlink-v8-fixedNoSn是2009的固件刷完执行下面的步骤后 会自动更新到2014版本...

    JLinkV8V9OB解决j-link-is-defective,j-link clone

    标题和描述中提到的问题"j-link-is-defective"和"j-link clone"指的是用户可能遇到了假冒的J-Link调试器或者J-Link在使用过程中出现了故障。这里我们将详细讨论如何识别和解决这些问题。 首先,"j-link-is-...

    Java深浅clone

    在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...

    Jlink-clone解决办法,替换文件.rar

    在IT行业中,Jlink通常指的是SEGGER公司的J-Link系列编程和调试接口,它广泛用于嵌入式系统开发,特别是针对ARM架构的设备。当遇到"Jlink-clone"问题时,这通常指的是遇到了非原厂生产的、可能功能受限或者不稳定...

    git clone 最新版

    数字递增表示重要性,大版本号改变通常意味着重大更新,小版本号增加可能包含新功能,修订号增加则主要是bug修复。因此,2.29.2比2.28.0更先进,因为它包含了更多的改进和修复。 安装Git后,`git clone`命令将在你...

    jQuery Clone Bug解决代码

    jQuery Clone Bug 解决代码 jQuery Clone Bug 是一个常见的 jQuery bug,导致在克隆 DOM 元素时,事件处理函数被无限递归调用。下面是解决该 bug 的代码和相关知识点。 事件绑定和 $.data() 方法 在 jQuery 中,...

    Clone详解.doc

    `Object`类中的`clone()`方法是`protected`的,这样可以防止其他类随意克隆不期望被克隆的对象。在`Employee`类中,由于继承了`Object`,因此可以直接访问并重写`clone()`方法,实现自定义的克隆逻辑。 5. 使用...

Global site tag (gtag.js) - Google Analytics