Skip to content

Commit 58ec25d

Browse files
author
Poonam Bajaj
committedApr 28, 2022
8201793: (ref) Reference object should not support cloning
Reviewed-by: mchung, kbarrett, iris Backport-of: bd18ef4c18081d04c89ee9f94e98fd2ef1e2bf38
1 parent 330d63d commit 58ec25d

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
 

‎jdk/src/share/classes/java/lang/ref/Reference.java

+17
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,23 @@ public boolean enqueue() {
244244
return this.queue.enqueue(this);
245245
}
246246

247+
248+
/**
249+
* Throws {@link CloneNotSupportedException}. A {@code Reference} cannot be
250+
* meaningfully cloned. Construct a new {@code Reference} instead.
251+
*
252+
* @apiNote This method is defined in Java SE 8 Maintenance Release 4.
253+
*
254+
* @return never returns normally
255+
* @throws CloneNotSupportedException always
256+
*
257+
* @since 8
258+
*/
259+
@Override
260+
protected Object clone() throws CloneNotSupportedException {
261+
throw new CloneNotSupportedException();
262+
}
263+
247264
/* -- Constructors -- */
248265

249266
Reference(T referent) {
+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8201793
27+
* @summary Test Reference::clone to throw CloneNotSupportedException
28+
*/
29+
30+
import java.lang.ref.*;
31+
32+
public class ReferenceClone {
33+
private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<>();
34+
public static void main(String... args) {
35+
ReferenceClone refClone = new ReferenceClone();
36+
refClone.test();
37+
}
38+
39+
public void test() {
40+
// test Reference::clone that throws CNSE
41+
Object o = new Object();
42+
assertCloneNotSupported(new SoftRef(o));
43+
assertCloneNotSupported(new WeakRef(o));
44+
assertCloneNotSupported(new PhantomRef(o));
45+
46+
// Reference subclass may override the clone method
47+
CloneableReference ref = new CloneableReference(o);
48+
try {
49+
ref.clone();
50+
} catch (CloneNotSupportedException e) {}
51+
}
52+
53+
private void assertCloneNotSupported(CloneableRef ref) {
54+
try {
55+
ref.clone();
56+
throw new RuntimeException("Reference::clone should throw CloneNotSupportedException");
57+
} catch (CloneNotSupportedException e) {}
58+
}
59+
60+
// override clone to be public that throws CNSE
61+
interface CloneableRef extends Cloneable {
62+
public Object clone() throws CloneNotSupportedException;
63+
}
64+
65+
class SoftRef extends SoftReference<Object> implements CloneableRef {
66+
public SoftRef(Object referent) {
67+
super(referent, QUEUE);
68+
}
69+
public Object clone() throws CloneNotSupportedException {
70+
return super.clone();
71+
}
72+
}
73+
74+
class WeakRef extends WeakReference<Object> implements CloneableRef {
75+
public WeakRef(Object referent) {
76+
super(referent, QUEUE);
77+
}
78+
public Object clone() throws CloneNotSupportedException {
79+
return super.clone();
80+
}
81+
}
82+
83+
class PhantomRef extends PhantomReference<Object> implements CloneableRef {
84+
public PhantomRef(Object referent) {
85+
super(referent, QUEUE);
86+
}
87+
88+
public Object clone() throws CloneNotSupportedException {
89+
return super.clone();
90+
}
91+
}
92+
93+
// override clone to return a new instance
94+
class CloneableReference extends WeakReference<Object> implements Cloneable {
95+
public CloneableReference(Object referent) {
96+
super(referent, QUEUE);
97+
}
98+
99+
public Object clone() throws CloneNotSupportedException {
100+
return new CloneableReference(this.get());
101+
}
102+
}
103+
104+
}

0 commit comments

Comments
 (0)