Summary
-------
Update the class hierarchy in `java.lang.ref` that could not be user-extended to use sealed classes.
Problem
-------
The classes in `java.lang.ref`, the root class `Reference` and its subclasses `PhantomReference`, `SoftReference`, and `WeakReference`, form a set of related classes where `Reference` cannot be directly extended by users but its subclasses can. This intention can be represented using sealed classes.
Solution
--------
Update the classes in question so that `Reference` is sealed but its subclasses are non-sealed, retaining their subclassability.
Specification
-------------
(Note that as an implementation detail, the non-public class `FinalReference` can also subclass `Reference`, but this is not a visible change to the public API.)
diff --git a/src/java.base/share/classes/java/lang/ref/PhantomReference.java b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
index 2c1532b8eb2..71947101e9c 100644
--- a/src/java.base/share/classes/java/lang/ref/PhantomReference.java
+++ b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
@@ -50,7 +50,7 @@
* @since 1.2
*/
-public class PhantomReference<T> extends Reference<T> {
+public non-sealed class PhantomReference<T> extends Reference<T> {
/**
* Returns this reference object's referent. Because the referent of a
diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java
index 17d8c7b669c..75c8f3544dc 100644
--- a/src/java.base/share/classes/java/lang/ref/Reference.java
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java
@@ -41,7 +41,8 @@
* @since 1.2
*/
-public abstract class Reference<T> {
+public abstract sealed class Reference<T>
+ permits PhantomReference, SoftReference, WeakReference, FinalReference {
/* The state of a Reference object is characterized by two attributes. It
* may be either "active", "pending", or "inactive". It may also be
diff --git a/src/java.base/share/classes/java/lang/ref/SoftReference.java b/src/java.base/share/classes/java/lang/ref/SoftReference.java
index 8ce74a67d0a..b57e52bf766 100644
--- a/src/java.base/share/classes/java/lang/ref/SoftReference.java
+++ b/src/java.base/share/classes/java/lang/ref/SoftReference.java
@@ -61,7 +61,7 @@
* @since 1.2
*/
-public class SoftReference<T> extends Reference<T> {
+public non-sealed class SoftReference<T> extends Reference<T> {
/**
* Timestamp clock, updated by the garbage collector
diff --git a/src/java.base/share/classes/java/lang/ref/WeakReference.java b/src/java.base/share/classes/java/lang/ref/WeakReference.java
index fdf2b5c9f02..966f7f1b26c 100644
--- a/src/java.base/share/classes/java/lang/ref/WeakReference.java
+++ b/src/java.base/share/classes/java/lang/ref/WeakReference.java
@@ -45,7 +45,7 @@
* @since 1.2
*/
-public class WeakReference<T> extends Reference<T> {
+public non-sealed class WeakReference<T> extends Reference<T> {
/**
* Creates a new weak reference that refers to the given object. The new