On 11.03.2018 20:22, Rony G. Flatscher wrote:
> Well, still trying to find out what the reason is, that core reflection's
> invoke behaves
> differently to MethodHandle's invokeWithArguments in one single case so far
> (using the method
> java.utli.Arrays.asList(...)).
>
> Here is a little Java program that excercises reflective access to
> "java.util.Arrays.asList(T... a)" using core reflection, i.e.
> "Method.invoke(Object obj,
> Object... args)" and "MethodHandle.invokeWithArguments(Object... arguments)":
>
> import java.util.*;
>
> import java.lang.reflect.*;
> import java.lang.invoke.*;
>
> class DemoAsListProblem
> {
> public static void main (String args[])
> {
> String arrNames[]=new String[] { "anne", "bert", "celine"};
> System.out.println("[1] (main) arrNames=\""+arrNames+"\",
> .toString()=\""+arrNames.toString()+"\"");
> List listNames=Arrays.asList(arrNames);
> System.out.println("[2] (main) after invoking
> Arrays.asList(arrNames), listNames=\""+listNames+"\"");
> System.out.println("\ninvoking testReflective() ...\n");
>
> testReflective();
> }
>
> public static void testReflective()
> {
> String arrNames[]=new String[] { "anne", "bert", "celine"};
> System.out.println("[3] (testReflective)
> arrNames=\""+arrNames+"\", .toString()=\""+arrNames.toString()+"\"");
>
> Method methAsList=null;
> List listNames=null;
> try {
> Class paramTypes[]=new Class[] { (new Object[0]).getClass() };
> methAsList=Arrays.class.getDeclaredMethod("asList",
> paramTypes);
> System.out.println("--- (core reflection) Method object
> asList: "+methAsList);
> System.out.println("\n--- (core reflection) now invoking
> Arrays.asList() via Method.invoke(...):");
>
> listNames=(List) methAsList.invoke( null, (Object[]) new
> Object[]{arrNames} ); // static method
> System.out.println("[4a] --- (CR) methAsList.invoke( null,
> (Object[]) new Object[]{arrNames} ) -> listNames=\""+listNames+"\"");
>
> listNames=(List) methAsList.invoke( null, (Object) new
> Object[]{arrNames} ); // static method
> System.out.println("[4b] --- (CR) methAsList.invoke( null,
> (Object) new Object[]{arrNames} ) -> listNames=\""+listNames+"\"");
>
> // "java.lang.IllegalArgumentException: wrong number of arguments":
> // listNames=(List) methAsList.invoke( null, (Object[])
> arrNames ); // static method
> // System.out.println("[5a] --- (CR) methAsList.invoke( null,
> (Object[]) arrNames ) -> listNames=\""+listNames+"\"");
>
> listNames=(List) methAsList.invoke( null, (Object) arrNames
> ); // static method
> System.out.println("[5b] --- (CR) methAsList.invoke( null,
> (Object) arrNames ) -> listNames=\""+listNames+"\"");
> }
> catch (Throwable t)
> {
> System.err.println("oops #1: "+t);
> t.printStackTrace();
> System.exit(-1);
> }
>
> System.out.println("\n--- (MH) now invoking Arrays.asList() via
> MethodHandle.invokeWithArguments(...):");
> MethodHandles.Lookup lookup=MethodHandles.lookup();
> MethodHandle mh=null;
> try {
> mh=lookup.unreflect(methAsList);
> System.out.println("--- (MH) unreflected MethodHandle mh:
> "+mh);
>
> listNames=(List) mh.invokeWithArguments( (Object[]) new
> Object[]{arrNames} );
> System.out.println("[6a] --- (MH) mh.invokeWithArguments(
> (Object[]) new Object[]{arrNames} ) -> listNames=\""+listNames+"\"");
>
> listNames=(List) mh.invokeWithArguments( (Object) new
> Object[]{arrNames} );
> System.out.println("[6b] --- (MH) mh.invokeWithArguments(
> (Object) new Object[]{arrNames} ) -> listNames=\""+listNames+"\"");
>
> listNames=(List) mh.invokeWithArguments( (Object[]) arrNames
> );
> System.out.println("[7a] --- (MH) mh.invokeWithArguments(
> (Object[]) arrNames ) -> listNames=\""+listNames+"\"");
>
> listNames=(List) mh.invokeWithArguments( (Object) arrNames );
> System.out.println("[7b] --- (MH) mh.invokeWithArguments(
> (Object) arrNames ) -> listNames=\""+listNames+"\"");
>
> }
> catch (Throwable t)
> {
> System.err.println("oops #2: "+t);
> t.printStackTrace();
> System.exit(-2);
> }
> }
> }
>
> Compiling and running it under 9.0.4 yields the following output:
>
> [1] (main) arrNames="[Ljava.lang.String;@27ddd392",
> .toString()="[Ljava.lang.String;@27ddd392"
> [2] (main) after invoking Arrays.asList(arrNames), listNames="[anne,
> bert, celine]"
>
> invoking testReflective() ...
>
> [3] (testReflective) arrNames="[Ljava.lang.String;@2a18f23c",
> .toString()="[Ljava.lang.String;@2a18f23c"
> --- (core reflection) Method object asList: public static java.util.List
> java.util.Arrays.asList(java.lang.Object[])
>
> --- (core reflection) now invoking Arrays.asList() via Method.invoke(...):
> [4a] --- (CR) methAsList.invoke( null, (Object[]) new Object[]{arrNames}
> ) -> listNames="[anne, bert, celine]"
> [4b] --- (CR) methAsList.invoke( null, (Object) new Object[]{arrNames}
> ) -> listNames="[[Ljava.lang.String;@2a18f23c]"
> [5b] --- (CR) methAsList.invoke( null, (Object) arrNames )
> -> listNames="[anne, bert, celine]"
>
> --- (MH) now invoking Arrays.asList() via
> MethodHandle.invokeWithArguments(...):
> --- (MH) unreflected MethodHandle mh: MethodHandle(Object[])List
> [6a] --- (MH) mh.invokeWithArguments( (Object[]) new Object[]{arrNames}
> ) -> listNames="[[Ljava.lang.String;@2a18f23c]"
> [6b] --- (MH) mh.invokeWithArguments( (Object) new Object[]{arrNames}
> ) -> listNames="[[Ljava.lang.Object;@13a57a3b]"
> [7a] --- (MH) mh.invokeWithArguments( (Object[]) arrNames )
> -> listNames="[anne, bert, celine]"
> [7b] --- (MH) mh.invokeWithArguments( (Object) arrNames )
> -> listNames="[[Ljava.lang.String;@2a18f23c]"
>
> So a String array is turned into a List using Arrays.asList(strArray). Doing
> it with core
> reflection yields different results to doing it with invokeWithArguments().
>
> I would have expected that [4a] and [6a] would behave the same.
>
> Using reflective invoke() and invokeWithArguments() has been working for my
> bridge for all the
> test units (using literally the same arguments in both cases)
> interchangeably, the one exception
> is Arrays.asList().
>
> Maybe I am not seeing the obvious (having done too much "close-up tests" for
> quite some time now).
> So any hint, insight, help would be really appreciated!
>
> ---rony
As a few months have gone by without any follow-ups, I have been wondering
whether there is a
solution at all, if this is a problem rooted in the current implementation of
MethodHandle methods
not being 100% compatible with reflective invoke (which may imply that one
needs to stick to use
reflective invoke and forgo MethodHandle invokes for good).
---rony
_______________________________________________
mlvm-dev mailing list
[email protected]
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev