- 浏览: 68646 次
- 性别:
- 来自: 北京
文章分类
最新评论
Why clone() is protected rather than public,it's a bug
- 博客分类:
- Reading Notes
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., "new String(blah)", 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("clone", 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 "conventional copy" 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 |
发表评论
-
How to be a Programmer: A Short,Comprehensive,and Personal Summary
2013-10-28 10:38 545well written. http://samizdat ... -
js module pattern
2013-10-12 16:21 358http://www.adequatelygood.com/ ... -
GZip compressing HTML, JavaScript, CSS etc. makes the data sent to the browser s
2013-07-31 15:48 629this is fun. http://tutorials ... -
java collection matrix
2012-08-07 11:24 697http://www.janeve.me/articles/w ... -
ghost text (aka in-field text)
2012-04-01 11:18 630http://archive.plugins.jquery.c ... -
What is Optimistic Locking vs. Pessimistic Locking
2011-09-09 16:50 794What is Optimistic Locking vs. ... -
what is DAO
2011-04-15 13:42 732http://java.sun.com/blueprints/ ... -
indenting xml in vim with xmllint
2011-01-10 09:48 670I added to my “.vimrc” file: ... -
css sprite
2010-12-15 16:57 604http://css-tricks.com/css-sprit ... -
最牛B 的 Linux Shell 命令
2010-10-30 00:08 673http://hi.baidu.com/hy0kl/blog/ ... -
GPS Bearing VS Heading
2010-10-21 15:40 1638http://gps.about.com/od/glossar ... -
Document Type Declaration
2010-07-19 22:01 797Document Type Declaration h ... -
XML Declaration must be the first line in the document.
2010-06-12 17:54 857The XML declaration typically a ... -
UCM
2010-05-08 11:41 709Two links about UCM The power ... -
What is an MXBean?
2010-01-28 11:10 691refer to http://weblogs.java. ... -
why wait() always in a loop
2010-01-19 00:17 812As we know ,jdk API doc suggest ... -
Locks in Java
2010-01-18 22:48 900copied from http://tutorials.je ... -
use jps instead of ps to find jvm process
2010-01-11 14:21 777copied from http://java.sun.com ... -
My first error of Hello Wolrd Struts
2010-01-04 09:10 840It's my first time to touch Str ... -
Unit Testing Equals and HashCode of Java Beans
2009-12-29 10:07 1277copy from http://blog.cornetdes ...
相关推荐
在使用高版本版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++...
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 ...
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 ...
终于是搞好了几个固件都可以自动升级,可以用官网最新版驱动7.64b、7.65a等等,完美运行完美调试 使用方法:LINK-V8/ JLINK-OB刷入固件,(jlink-v8-fixedNoSn是2009的固件刷完执行下面的步骤后 会自动更新到2014版本...
This project is a very sinple clone of "ls".
试试吧
kanban, Kanban 看板 is a Trello clone in Rails and Backbone.js.zip
This functionality makes it possible to move a Backup Domain Controller (BDC) to a new Domain, since a BDC‘s relationship to a Domain is identified by it having the same computer SID as the other ...
Jlink-clone解决办法,替换文件
测试发现,textarea和select的jquery的clone方法有问题,textarea和select的值clone的时候会丢掉,发现这个是jquery的一个bug,上不了的可以看下代码,比较简单。就是在clone的时候将val再重新赋值一下,如果知道这个...
(实战)[re:Invent 2018]-001:赛道分析-(致敬1024) 配套 train and evaluation log
Clone 属性的相关内容 Clone 属性的相关内容
git clone 最新版 不多说上资源 好用测试ok git clong git clone 最新版 不多说上资源 好用测试ok git clong
jQuery Clone Bug解决代码,具体看测试代码。
本人用的JLINK仿真器.在使用新版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示。在网上找了许多关于修复的资料,都觉得不是很好。经过本人反复试验,总算找到比较好的解决方案,操作步骤如下
Clone10-EX-LV2
The code is very rough and it could use a lot of optimization and polish but it’s playable. It works best on Windows and I also tested it on Android and IOS but not OSX. It uses a TMemIniFile to ...
jquery.clone
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。