Hi Peter, Daniel

On 7/31/19 1:44 AM, Peter Levart wrote:


On 7/31/19 9:59 AM, Peter Levart wrote:
Hi,

I think Daniel is talking about the "dispatch" semantics of unreflectSpecial here, right Daniel?


Thanks for clarifying this.

The findSpecial / unreflectSpecial is a MethodHandle equivalent for bytecode instruction invokespecial (sans actual invoking). invokespecial is typically used for implementing the super.method(args) Java invocations. In that case, the superclass method is targeted - this is not a virtual method dispatch like aMethod.invoke(this, arg*) - i.e. the reflective invocation is always a virtual invocation (for non-private methods). Likewise findSpecial and unreflectSpecial produce a MethodHandle that dispatches to the method in the superclass (the aMethod.getDeclatingClass() in case of unreflectSpecial) regardless of whether that method is overridden in the subclass or not.


Expanding on this a little. The javadocs of MethodHandles.Lookup starts talking about the Lookup factory methods methods and their equivalence to bytecode instructions, but then present the equivalence between find* and Java source code (which is OK given that translation to bytecode is known) followed by equivalence between unreflect* and reflective invocations. Public reflection API does not implement the equivalent behavior to unreflectSpecial. So perhaps, this line only could present the equivalence in terms of Java code like findSpecial does with a comment stating that there's no equivalence with reflective invocation API. For example:

     * <tr>
     *     <th scope="col"><a id="equiv"></a>lookup expression</th>
     *     <th scope="col">member</th>
     *     <th scope="col">bytecode / reflection behavior</th>

Added "/ reflection" above; and:


I prefer to keep the original header and revisit this separately. It intends to talk about bytecode behavior and perhaps handle this unreflect* exception differently.

     * <tr>
     *     <th scope="row">{@link java.lang.invoke.MethodHandles.Lookup#unreflectSpecial lookup.unreflectSpecial(aMethod,this.class)}</th>      *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*); // no equivalent reflective invocation}</td>
     * </tr>


This is correct when this class is a subclass of C.   A slight clarification to indicate that aMethod's declaring class is C might help.  I also fixed another typo:

--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
@@ -334,7 +334,7 @@
      * </tr>
      * <tr>
      *     <th scope="row">{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter 
lookup.findStaticGetter(C.class,"f",FT.class)}</th>
-     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (FT) C.f;}</td>
      * </tr>
      * <tr>
      *     <th scope="row">{@link java.lang.invoke.MethodHandles.Lookup#findSetter 
lookup.findSetter(C.class,"f",FT.class)}</th>
@@ -377,8 +377,8 @@
      *     <td>{@code C(A*);}</td><td>{@code (C) 
aConstructor.newInstance(arg*);}</td>
      * </tr>
      * <tr>
-     *     <th scope="row">{@link java.lang.invoke.MethodHandles.Lookup#unreflect 
lookup.unreflect(aMethod)}</th>
-     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) 
aMethod.invoke(thisOrNull, arg*);}</td>
+     *     <th scope="row">{@link 
java.lang.invoke.MethodHandles.Lookup#unreflectSpecial 
lookup.unreflectSpecial(aMethod,this.class)}</th>
+     *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
      * </tr>
      * <tr>
      *     <th scope="row">{@link java.lang.invoke.MethodHandles.Lookup#findClass 
lookup.findClass("C")}</th>
@@ -403,7 +403,7 @@
      * stands for a null reference if the accessed method or field is static,
      * and {@code this} otherwise.
      * The names {@code aMethod}, {@code aField}, and {@code aConstructor} 
stand
-     * for reflective objects corresponding to the given members.
+     * for reflective objects corresponding to the given members declared in 
type {@code C}.
      * <p>
      * The bytecode behavior for a {@code findClass} operation is a load of a 
constant class,
      * as if by {@code ldc CONSTANT_Class}.


Thanks.
Mandy

Reply via email to