-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
low
-
-
Java API
-
SE
Summary
- MethodHandleProxies.asInterfaceInstance is no longer based on Proxy.
- Documents that asInterfaceInstance rejects hidden interfaces.
Problem
- Instances created by MethodHandleProxies.asInterfaceInstance uses Proxy, which is a heavy wrapper and exposes additional implementation details, such as a Proxy superclass and marker interfaces. Proxy also prevents asInterfaceInstance from implementing SAM abstract classes in the future.
- asInterfaceInstance already rejects hidden interfaces as Proxy does, but it is not explicitly documented.
Solution
- To allow future extensibility and improve performance, the implementation was switched to hidden classes that store method handles as fields. A hidden class is defined for each interface. The implementation class is defined in a dynamic module such that the implementation class is fully encapsulated. The dynamic module is defined to the class loader of the interface. The hidden classes will be unloaded if the instances become unreachable even the defining loader is strongly reachable.
- Explicitly specify that the provided interface must not be hidden.
Compatibility
All the behavior changes conform to the existing and updated API specification and is correct.
The caching mechanism now differs that asInterfaceInstance may create new wrapper classes once the old wrapper classes are unloaded (meaning no wrapper is reachable), while Proxy classes are not unloaded.
Inspection under reflection will change: no more marker interface and Proxy superclass, and some details to the wrapper module changes.
- asInterfaceInstance already rejects hidden interfaces with IAE as Proxy does, so the specification change has minimal impact.
Specification
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
@@ -82,7 +83,8 @@ private MethodHandleProxies() { } // do not instantiate
* even though it re-declares the {@code Object.equals} method and also
* declares default methods, such as {@code Comparator.reverse}.
* <p>
- * The interface must be public and not {@linkplain Class#isSealed() sealed}.
+ * The interface must be public, not {@linkplain Class#isHidden() hidden},
+ * and not {@linkplain Class#isSealed() sealed}.
* No additional access checks are performed.
* <p>
* The resulting instance of the required type will respond to
- csr of
-
JDK-6983726 Reimplement MethodHandleProxies.asInterfaceInstance
-
- Resolved
-