When to initialize the method's class for MethodHandles.Lookup.findStatic()?

Raffaello Giulietti raffaello.giulietti at gmail.com
Fri Mar 18 00:11:39 UTC 2022


Sure, which again shows that Test_2 is not initialized by the lookup of 
the mh but only upon its invocation.

Raffaello


On 2022-03-18 00:46, David Holmes wrote:
> Run with -Xlog:class+init=info to see the classes that get initialized 
> and in what order.
> 
> David
> 
> On 18/03/2022 5:53 am, Raffaello Giulietti wrote:
>> Hi again,
>>
>> here's code that shows that initialization doesn't happen during 
>> lookup but only upon invoking the method handle. (I'm on Java 17.)
>>
>> As long as the 2nd line in main() is commented, you don't see the 
>> message "Test_2 initialized", which shows that the lookup doesn't 
>> initialize Test_2.
>> When you uncomment the line in main(), the message will appear.
>>
>> So, as advertised, it's the invocation of the method handle that can 
>> trigger initialization, not the lookup.
>>
>>
>> HTH
>> Raffaello
>>
>> ----
>>
>> import java.lang.invoke.*;
>>
>> public class Test_1 {
>>
>>      static MethodHandle mh;
>>
>>      static {
>>          try {
>>              mh = MethodHandles.lookup().findStatic(Test_2.class, 
>> "testMethod", MethodType.methodType(int.class, int.class));
>>          } catch (NoSuchMethodException | IllegalAccessException e) {
>>              e.printStackTrace();
>>          }
>>      }
>>
>>      public static void main(String[] args) throws Throwable {
>>          System.out.println(mh);
>>          // System.out.println(Test_1.mh.invoke(0));
>>      }
>>
>> }
>>
>>
>>
>>
>> public class Test_2 {
>>
>>      static {
>>          System.out.println("Test_2 initialized");
>>      }
>>
>>      static int testMethod(int value) { return (value + 1); }
>>
>> }
>>
>>
>>
>>
>> On 2022-03-17 20:38, Raffaello Giulietti wrote:
>>> Hi,
>>>
>>> as far as I can see, the code should not even compile, as there's a 
>>> static field in Test_1 which is initialized with an expression that 
>>> throws checked exceptions (findStatic(..)).
>>>
>>> In addition, it seems to me that there's nothing in your code that 
>>> reveals whether Test_2 has been initialized during the lookup. How 
>>> can you tell?
>>>
>>> Finally, the method handle invocation in Test_1 will throw, as you 
>>> don't pass any argument to a handle that expects one.
>>>
>>> Can you perhaps add more details?
>>>
>>>
>>> Greetings
>>> Raffaello
>>>
>>>
>>>
>>> On 2022-03-17 17:42, Cheng Jin wrote:
>>>> Hi there,
>>>>
>>>> The document of 
>>>> https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html#findStatic(java.lang.Class,java.lang.String,java.lang.invoke.MethodType) 
>>>> in the Java API is ambiguous in terms of when to initialize the 
>>>> method's class as follows (the same description as in other OpenJDK 
>>>> versions)
>>>>
>>>> If the returned method handle is invoked, the method's class will be 
>>>> initialized, if it has not already been initialized.
>>>>
>>>>
>>>> It occurs to me that the method's class should be initialized when 
>>>> invoking the method handle but OpenJDK actually chooses to do the 
>>>> initialization in lookup.findStatic() rather than in mh.invoke()
>>>> e.g.
>>>> import java.lang.invoke.*;
>>>>
>>>> public class Test_1 {
>>>>      static MethodHandle mh = 
>>>> MethodHandles.lookup().findStatic(Test_2.class, "testMethod", 
>>>> MethodType.methodType(int.class, int.class)); <----------- 
>>>> Test_2.class gets initialized and verified.
>>>>
>>>>      public static void main(String[] args) throws Throwable {
>>>>          Test_1.mh.invoke();
>>>>      }
>>>> }
>>>>
>>>> public class Test_2 {
>>>>      static int testMethod(int value) { return (value + 1); }
>>>> }
>>>>
>>>> So there should be more clear explanation what is the correct or 
>>>> expected behaviour at this point and why OpenJDK doesn't comply with 
>>>> the document to delay the initialization of the method's class to 
>>>> mh.invoke().
>>>>
>>>> Best Regards
>>>> Cheng Jin


More information about the core-libs-dev mailing list