View Javadoc
1   /*
2    * Copyright 2025 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package java.lang.invoke;
17  
18  /**
19   * A stub for the VarHandle class.<br>
20   * This stub is used to allow Java 8 release compilation to work as expected.
21   * The sole limit of this stub is that since {@code java.lang.invoke} is a privileged package
22   * it cannot be used at runtime (e.g. loaded by a classloader).<p>
23   * For example, if {@code SomeClass} is loaded at runtime:
24   * <pre>
25   *     class SomeClass {
26   *          private static final VarHandle VH = // ... obtained somehow;
27   *
28   *          public static void storeStoreFence() {
29   *              if (VH == null) {
30   *                  return;
31   *              }
32   *              VH.storeStoreFence();
33   *          }
34   *     }
35   * </pre>
36   * this is not going to work on Java 8.<p>
37   * To fix it is possible to use an holder class (which won't be loaded at runtime):
38   * <pre>
39   *     class SomeClass {
40   *          static class Holder {
41   *              private static final VarHandle VH = // ... obtained somehow;
42   *          }
43   *
44   *          public static void storeStoreFence() {
45   *              VarHandle vh = Holder.VH;
46   *              if (vh == null) {
47   *                  return;
48   *              }
49   *              vh.storeStoreFence();
50   *          }
51   *     }
52   * </pre>
53   * Or:
54   * <pre>
55   *     class SomeClass {
56   *          private static final Object VH = // ... obtained somehow;
57   *
58   *          public static void storeStoreFence() {
59   *              if (VH == null) {
60   *                  return;
61   *              }
62   *              ((VarHandle)VH).storeStoreFence();
63   *          }
64   *     }
65   * </pre>
66   *
67   * The reason why the methods on the stub are declared as native is to allow
68   * {@link java.lang.invoke.MethodHandle.PolymorphicSignature} to work as expected,
69   * see <a href="https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.12.3">JLS 15.12.3</a>:<br>
70   * <pre>
71   *   A method is signature polymorphic if all of the following are true:
72   *   - It is declared in the java.lang.invoke.MethodHandle class or the java.lang.invoke.VarHandle class.
73   *   - It has a single variable arity parameter (§8.4.1) whose declared type is Object[].
74   *   - It is native.
75   * </pre>
76   * This seems counter-intuitive since this stub is not going to be used at runtime, but it is required to allow Java 8
77   * compilation to produce {@code VarHandle}'s method invocations with parameters and result types with
78   * the types of the formal ones of the compile-time declaration.
79   *
80   */
81  public class VarHandle {
82  
83      @MethodHandle.PolymorphicSignature
84      public native Object get(Object... args);
85  
86      @MethodHandle.PolymorphicSignature
87      public native Object getAcquire(Object... args);
88  
89      @MethodHandle.PolymorphicSignature
90      public native void set(Object... args);
91  
92      @MethodHandle.PolymorphicSignature
93      public native void setRelease(Object... args);
94  
95      @MethodHandle.PolymorphicSignature
96      public native Object getAndAdd(Object... args);
97  
98      @MethodHandle.PolymorphicSignature
99      public native boolean compareAndSet(Object... args);
100 
101     public static void storeStoreFence() {
102         throw new UnsupportedOperationException("Not implemented in varhandle-stub");
103     }
104 }