# HG changeset patch # User mchung # Date 1525371537 25200 # Node ID e3653598e3b09aecd89530f15db8b41b5e811520 # Parent 37b2446d7f86789658a1a485f15300a5184a0a07 8201793: (ref) Reference object should not support cloning Reviewed-by: psandoz, kbarrett diff -r 37b2446d7f86 -r e3653598e3b0 src/java.base/share/classes/java/lang/ref/Reference.java --- a/src/java.base/share/classes/java/lang/ref/Reference.java Thu May 03 09:07:40 2018 -0700 +++ b/src/java.base/share/classes/java/lang/ref/Reference.java Thu May 03 11:18:57 2018 -0700 @@ -300,6 +300,20 @@ return this.queue.enqueue(this); } + /** + * Throws {@link CloneNotSupportedException}. A {@code Reference} cannot be + * meaningfully cloned. Construct a new {@code Reference} instead. + * + * @returns never returns normally + * @throws CloneNotSupportedException always + * + * @since 11 + */ + @Override + protected Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + /* -- Constructors -- */ Reference(T referent) { diff -r 37b2446d7f86 -r e3653598e3b0 test/jdk/java/lang/ref/ReferenceClone.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/ref/ReferenceClone.java Thu May 03 11:18:57 2018 -0700 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8201793 + * @summary Test Reference::clone to throw CloneNotSupportedException + */ + +import java.lang.ref.*; + +public class ReferenceClone { + private static final ReferenceQueue QUEUE = new ReferenceQueue<>(); + public static void main(String... args) { + ReferenceClone refClone = new ReferenceClone(); + refClone.test(); + } + + public void test() { + // test Reference::clone that throws CNSE + Object o = new Object(); + assertCloneNotSupported(new SoftRef(o)); + assertCloneNotSupported(new WeakRef(o)); + assertCloneNotSupported(new PhantomRef(o)); + + // Reference subclass may override the clone method + CloneableReference ref = new CloneableReference(o); + try { + ref.clone(); + } catch (CloneNotSupportedException e) {} + } + + private void assertCloneNotSupported(CloneableRef ref) { + try { + ref.clone(); + throw new RuntimeException("Reference::clone should throw CloneNotSupportedException"); + } catch (CloneNotSupportedException e) {} + } + + // override clone to be public that throws CNSE + interface CloneableRef extends Cloneable { + public Object clone() throws CloneNotSupportedException; + } + + class SoftRef extends SoftReference implements CloneableRef { + public SoftRef(Object referent) { + super(referent, QUEUE); + } + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + class WeakRef extends WeakReference implements CloneableRef { + public WeakRef(Object referent) { + super(referent, QUEUE); + } + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + class PhantomRef extends PhantomReference implements CloneableRef { + public PhantomRef(Object referent) { + super(referent, QUEUE); + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + // override clone to return a new instance + class CloneableReference extends WeakReference implements Cloneable { + public CloneableReference(Object referent) { + super(referent, QUEUE); + } + + public Object clone() throws CloneNotSupportedException { + return new CloneableReference(this.get()); + } + } + +}