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