モジュール java.base
パッケージ java.lang.invoke

クラスCallSite

  • 直系の既知のサブクラス:
    ConstantCallSite, MutableCallSite, VolatileCallSite

    public abstract class CallSite
    extends Object
    CallSiteは、ターゲットと呼ばれる変数MethodHandleのホルダーです。 CallSiteにリンクされたinvokedynamic命令は、すべての呼出しをそのサイトの現在のターゲットに委譲します。 CallSiteは、いくつかのinvokedynamic命令に関連付けることができ、どの命令にも関連付けられていないフリー・フローティングの状態にすることもできます。 いずれにしても、動的インボーカと呼ばれる関連付けられたメソッド・ハンドルを通じて呼び出すことができます。

    CallSiteは、ユーザーによる直接的なサブクラス化を許可しない抽象クラスです。 その直下には、インスタンス化やサブクラス化を行える具象サブクラスが3つあります。

    • 可変ターゲットが不要な場合は、定数コール・サイトを使ってinvokedynamic命令を永続的にバインドできます。
    • ターゲットへの更新をほかのスレッドから即時かつ確実に確認できる必要があるためにvolatile変数セマンティックスを持つ可変ターゲットが必要な場合には、揮発性コール・サイトを使用できます。
    • それ以外の場合に可変ターゲットが必要な場合は、可変コール・サイトを使用できます。

    定数でないコール・サイトは、ターゲット変更による再リンクが可能です。 新しいターゲットは以前のターゲットと同じを持つ必要があります。 したがって、1つのコール・サイトを一連のターゲットに次々と再リンクすることはできますが、その型を変更することはできません。

    コール・サイトとブートストラップ・メソッドを使用してすべての動的コール・サイトをリンクし、引数を出力する例を次に示します。

    
    static void test() throws Throwable {
        // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
        InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
    }
    private static void printArgs(Object... args) {
      System.out.println(java.util.Arrays.deepToString(args));
    }
    private static final MethodHandle printArgs;
    static {
      MethodHandles.Lookup lookup = MethodHandles.lookup();
      Class thisClass = lookup.lookupClass();  // (who am I?)
      printArgs = lookup.findStatic(thisClass,
          "printArgs", MethodType.methodType(void.class, Object[].class));
    }
    private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
      // ignore caller and name, but match the type:
      return new ConstantCallSite(printArgs.asType(type));
    }
    

    導入されたバージョン:
    1.7
    • メソッドの詳細

      • type

        public MethodType type()
        このコール・サイトのターゲットの型を返します。 ターゲットは変更可能ですが、すべてのコール・サイトの型は永続的であり、異なる型に変更することは決してできません。 setTargetメソッドはこの不変性を実現するため、以前のターゲットの型を持たない新しいターゲットをすべて拒否します。
        戻り値:
        現在のターゲットの型(将来のすべてのターゲットの型でもある)
      • dynamicInvoker

        public abstract MethodHandle dynamicInvoker()
        このコール・サイトにリンクされているinvokedynamic命令と同等のメソッド・ハンドルを生成します。

        このメソッドは次のコードと同等です。

        
         MethodHandle getTarget, invoker, result;
         getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
         invoker = MethodHandles.exactInvoker(this.type());
         result = MethodHandles.foldArguments(invoker, getTarget)
         

        戻り値:
        このコール・サイトの現在のターゲットを常に呼び出すメソッド・ハンドル