varHandle(Class, ByteOrder)
、varHandle(Class, long, ByteOrder)
を参照してください。)のいずれかから起動する必要があります。 これにより、変数型(すべてのプリミティブ・タイプをサポートしますが、void
とboolean
もサポートされます。)、およびメモリー・アクセスのvarハンドルに関連付けられた位置合わせ制約とバイト順序が決定されます。 結果として得られるメモリー・アクセス変数ハンドルを様々な方法で組み合せて、別のアドレス指定モードをエミュレートできます。 このクラスによって作成されるvarハンドルは、「必須」座標型(タイプMemorySegment
)と、間接参照が発生するセグメントに対するオフセット(バイト単位)を表すlong
座標型を特徴とします。
たとえば、次のように構築されたGroupLayout
インスタンスで表されるメモリー・レイアウトを考えます:
GroupLayout seq = MemoryLayout.structLayout( MemoryLayout.paddingLayout(32), MemoryLayout.valueLayout(32, ByteOrder.BIG_ENDIAN).withName("value") );
value
という名前のメンバーのレイアウトにアクセスするには、次のようにしてmemory access varハンドルを構築できます:
VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN); //(MemorySegment, long) -> int handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
特に指定がないかぎり、null
引数、またはこのクラスのメソッドに1つ以上のnull
要素を含む配列引数を渡すと、NullPointerException
がスローされます。
配置モードとアクセス・モード
メモリー・アクセス・メトリックのハンドルは、アクセス・サイズのS
および整列制約のB
(両方ともバイトで表します)に関連付けられています。 メモリー・アクセス操作が、位置合せ制約S
とB
の両方と互換性のあるメモリー・アドレスA
で発生する場合、「完全に整列」であるとします。 アクセスが完全に整列されている場合、次のアクセス・モードがサポートされ、原子性アクセスをサポートする保証があります:
- 32ビット・プラットフォーム上の
long
およびdouble
のアクセス・モードget
およびset
を除き、すべてのT
の読み取り/書き込みアクセス・モード。 int
、long
、float
またはdouble
のアトミック更新アクセス・モード。 (JDKの今後の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して追加の型をサポートする可能性があります。)int
およびlong
の数値アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)int
とlong
のビット単位アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)
T
がfloat
またはdouble
の場合、アトミック更新アクセス・モードでは、ビット単位表現(それぞれFloat.floatToRawIntBits(float)
とDouble.doubleToRawLongBits(double)
を参照してください)を使用して値が比較されます。
あるいは、メモリー・アクセス操作が、位置情報制約B
とのみ互換性のあるメモリー・アドレスA
で発生する場合、「部分的に整列」です。その場合、get
およびset
アクセス・モード以外でアクセスするとIllegalStateException
になります。 アクセスが部分的に整列されている場合、アトミック・アクセスは、A
およびS
のGCDを分割する2の最大電力に関してのみ保証されます。
最後に、他のすべてのケースでは、メモリー・アクセス操作は「右揃え」であると言っています; この場合、使用するアクセス・モードに関係なくIllegalStateException
がスローされます。
-
メソッドのサマリー
修飾子と型メソッド説明static VarHandle
asAddressVarHandle
(VarHandle target) 既存のvarハンドルを、キャリア・タイプがMemorySegment
の新しいvarハンドルに適応させます。static VarHandle
asUnsigned
(VarHandle target, Class<?> adaptedType) 受信値を絞り込み、指定された型との間で送信値を広げることで、ターゲット変数ハンドルを適応させます。static VarHandle
collectCoordinates
(VarHandle target, int pos, MethodHandle filter) フィルタ(メソッド・ハンドル)を使用して座標値のサブシーケンスを前処理することで、ターゲット変数ハンドルを適応させます。static VarHandle
dropCoordinates
(VarHandle target, int pos, Class<?>... valueTypes) ターゲットのvarハンドルに委譲する前にダミー座標を破棄するvarハンドルを返します。static VarHandle
filterCoordinates
(VarHandle target, int pos, MethodHandle... filters) 単項フィルタ関数を使用して着信座標値を前処理することで、ターゲット変数ハンドルを適応させます。static VarHandle
filterValue
(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) フィルタ関数のペアを使用して受信値と送信値を事前処理することで、ターゲット変数ハンドルを適応させます。static VarHandle
insertCoordinates
(VarHandle target, int pos, Object... values) Varハンドル呼出しの前に、1つ以上の「バインド座標」を持つターゲットvarハンドルを提供します。static VarHandle
permuteCoordinates
(VarHandle target, List<Class<?>> newCoordinates, int... reorder) 新しい座標が指定された座標と一致するように再配列することで、ターゲットのvarハンドルの座標値を適応させるvarハンドルを提供します。static VarHandle
指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。static VarHandle
指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。
-
メソッドの詳細
-
varHandle
指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。 戻されるvarハンドル・タイプはcarrier
で、座標タイプのリストは(MemorySegment, long)
です。long
座標タイプは、指定されたメモリー・セグメントへのバイト・オフセットに対応します。 返されるvarハンドルは、指定されたメモリー・セグメント内のオフセットにあるバイトにアクセスし、指定されたendiannessに従ってcarrier
型の値との間でバイトを構成します。生成されるメモリー・アクセスvarハンドルの境界整列制約(バイト単位)は、キャリア型carrier
のサイズ(バイト単位)と同じです。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
carrier
- キャリア・タイプ。 有効なキャリアは、byte
、short
、char
、int
、float
、long
およびdouble
です。byteOrder
- 必要なバイト順。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- 不正なキャリア・タイプが使用されている場合
-
varHandle
指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。 戻されるvarハンドル・タイプはcarrier
で、座標タイプのリストは(MemorySegment, long)
です。long
座標タイプは、指定されたメモリー・セグメントへのバイト・オフセットに対応します。 戻されたvarハンドルは、指定されたメモリー・セグメント内のオフセットにあるバイトにアクセスし、指定されたendiannessに従ってcarrier
型の値との間でバイトを構成します。結果として得られるメモリー・アクセスvarハンドルの位置合せ制約(バイト単位)は、alignmentBytes
によって指定されます。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
carrier
- キャリア・タイプ。 有効なキャリアは、byte
、short
、char
、int
、float
、long
およびdouble
です。alignmentBytes
- 位置合せ制約(バイト単位)です。 2の累乗である必要があります。byteOrder
- 必要なバイト順。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- 不正なキャリア・タイプが使用されている場合、またはalignmentBytes
が2の累乗でない場合。
-
asAddressVarHandle
既存のvarハンドルを、キャリア・タイプがMemorySegment
の新しいvarハンドルに適応させます。 つまり、戻されたvarハンドルでVarHandle.get(Object...)
をコールすると、読取り数値がメモリー・アドレス(MemoryAddress.ofLong(long)
をコールする場合と同様)に変換されます。同様に、VarHandle.set(Object...)
をコールすると、設定するメモリー・アドレスが数値に変換され、メモリーに書き込まれます。 (職責:至)メモリーから(resp.書込み)を読み取るバイト数は、元のメモリー・アクセス変数ハンドルのキャリアによって異なります。- パラメータ:
target
- 適応させるメモリー・アクセス変数ハンドル- 戻り値:
- 適応されたvarハンドル。
- 例外:
IllegalArgumentException
-varHandle
のキャリア・タイプがboolean
、float
またはdouble
のいずれかであるか、プリミティブ・タイプでない場合。
-
asUnsigned
受信値を絞り込み、指定された型との間で送信値を広げることで、ターゲット変数ハンドルを適応させます。返されたvarハンドルを使用すると、符号なしプリミティブ・データ型を、より広範囲の符号付きプリミティブ・タイプであるかのように簡単に扱うことができます。 たとえば、unsigned shortをJava
int
としてモデル化して、負の値を処理しないようにすると便利な場合があります。これは、Javashort
としてモデル化されている場合です。 これは次の例で説明します。MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope()); VarHandle SHORT_VH = MemoryLayouts.JAVA_SHORT.varHandle(short.class); VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class); SHORT_VH.set(segment, (short)-1); INT_VH.get(segment); // returns 65535
たとえば、結果のvarハンドルで
VarHandle.set(Object...)
をコールすると、受信値(型adaptedType
の)が「プリミティブ変換を狭める」によって変換され、target
varハンドルに渡されます。 ナロー・プリミティブ・コンバージョンでは、数値の全体的な大きさに関する情報が失われる場合があります。 逆に、結果のvarハンドルでVarHandle.get(Object...)
などをコールすると、target
varハンドルから取得された戻り値は、コール元に戻される前に「符号なしワイドニング変換」によって変換されます。 符号なしワイド変換では、target
キャリア・タイプより大きい上位ビットはゼロで、下位ビットの(target
キャリア・タイプの幅と等しい)はtarget
varハンドルから取得した値のビットと等しくなります。返されるvarハンドルは、変数の型
adaptedType
、同じアクセス座標、同じアクセス・モード(target
varハンドルで機能するものと同じアトミック・アクセス保証を備えています(VarHandle.AccessMode
および同じアトミック・アクセス保証を参照)。- パラメータ:
target
- 適応させるメモリー・アクセス変数ハンドルadaptedType
- 適応型- 戻り値:
- 適応されたvarハンドル。
- 例外:
IllegalArgumentException
-target
のキャリア・タイプがbyte
、short
またはint
のいずれでもない場合;adaptedType
がint
またはlong
のいずれでもない場合;adaptedType
のビット幅がadaptedType
キャリア・タイプのビット幅より大きくない場合。- Java言語仕様を参照してください:
-
5.1.3 プリミティブ・コンバージョンの解説
-
filterValue
public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) フィルタ関数のペアを使用して受信値と送信値を事前処理することで、ターゲット変数ハンドルを適応させます。たとえば、結果のvarハンドルで
VarHandle.set(Object...)
をコールすると、最初のフィルタを使用して受信値(T
タイプ。T
は最初のフィルタ関数のlastパラメータ・タイプです。)が処理され、ターゲットのvarハンドルに渡されます。 逆に、結果のvarハンドルでVarHandle.get(Object...)
などをコールすると、ターゲットのvarハンドル(T
タイプ。T
は、2番目のフィルタ関数のlastパラメータ・タイプです。)から取得された戻り値は、2番目のフィルタを使用して処理され、コール元に戻されます。VarHandle.AccessMode.COMPARE_AND_EXCHANGE
などのより高度なアクセス・モード・タイプでは、両方のフィルタが同時に適用される場合があります。ボクシングおよびアン・ボクシング・フィルタを整形式にするには、それぞれ
(A... , S) -> T
および(A... , T) -> S
の形式にする必要があります。T
はターゲット変数ハンドルの型です。 この場合、結果のvarハンドルはS
型になり、追加の座標A...
(ターゲット変数ハンドルの座標に追加されます。)を特徴とします。結果のvarハンドルは、ターゲットのvarハンドルで機能するアクセス・モードと同じアクセス・モードを備えています(
VarHandle.AccessMode
およびアトミック・アクセス保証を参照)。- パラメータ:
target
- ターゲット変数ハンドルfilterToTarget
- 一部のタイプのS
をtarget
のタイプに変換するフィルタfilterFromTarget
-target
のタイプをS
のタイプに変換するフィルタ- 戻り値:
- 指定されたボクシング/アン・ボクシング変換を実行して、新しい型を受け入れるアダプタ変数ハンドル。
- 例外:
IllegalArgumentException
-filterFromTarget
およびfilterToTarget
が整形式でない場合、つまり、(A... , S) -> T
および(A... , T) -> S
以外の型をそれぞれ持つ場合(T
はターゲット変数ハンドルの型)、またはfilterFromTarget
またはfilterToTarget
がチェック例外をスローする場合。
-
filterCoordinates
public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) 単項フィルタ関数を使用して着信座標値を前処理することで、ターゲット変数ハンドルを適応させます。たとえば、結果のvarハンドルで
VarHandle.get(Object...)
をコールすると、pos
(C1, C2 ... Cn
型。C1, C2 ... Cn
は単項フィルタ関数の戻り型です。)の位置から始まる着信座標値が新しい値(S1, S2 ... Sn
型。S1, S2 ... Sn
は単項フィルタ関数のパラメータ型です。)に変換され、(適応によって変更されていない座標とともに)がターゲットのvarハンドルに渡されます。座標フィルタを整形式にするには、その型が
S1 -> T1, S2 -> T1 ... Sn -> Tn
の形式である必要があります。ここで、T1, T2 ... Tn
はターゲット変数ハンドルのpos
位置から始まる座標型です。結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(
VarHandle.AccessMode
を参照してください)およびアトミック・アクセスが保証されます。- パラメータ:
target
- ターゲット変数ハンドルpos
- 変換する最初の座標の位置filters
- 位置pos
から座標を変換するために使用される単項関数- 戻り値:
- 指定された変換を新しい座標値に適用して、新しい座標型を受け入れるアダプタ変数ハンドル。
- 例外:
IllegalArgumentException
-filters
のハンドルが整形式でない場合、つまりS1 -> T1, S2 -> T2, ... Sn -> Tn
以外のタイプを持つ場合、T1, T2 ... Tn
は、ターゲットvarハンドルの位置pos
で始まる座標タイプであり、pos
が0とターゲットvarハンドル座標引数の間にない場合、またはpos
で始まる使用可能な座標タイプの数より多くのフィルタが指定されている場合は、いずれかの例外がスローされます。
-
insertCoordinates
Varハンドル呼出しの前に、1つ以上の「バインド座標」を持つターゲットvarハンドルを提供します。 その結果、結果のvarハンドルは、ターゲットのvarハンドルよりも座標型が少なくなります。たとえば、結果のvarハンドルで
VarHandle.get(Object...)
をコールすると、着信座標値がバインドされた座標値と結合され、ターゲットのvarハンドルに渡されます。バインドされた座標を整形式にするには、その型が
T1, T2 ... Tn
である必要があります。ここで、T1, T2 ... Tn
はターゲット変数ハンドルのpos
位置から始まる座標型です。結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(
VarHandle.AccessMode
を参照してください)およびアトミック・アクセスが保証されます。- パラメータ:
target
- バインドされた座標が挿入された後に呼び出すvarハンドルpos
- 挿入する最初の座標の位置values
- 挿入する一連のバウンド座標- 戻り値:
- ターゲットのvarハンドルを呼び出す前に、追加の座標を挿入するアダプタのvarハンドル
- 例外:
IllegalArgumentException
-pos
が0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合、またはpos
から使用可能な座標タイプの実際の数よりも多くの値が指定されている場合。ClassCastException
-values
のバインドされた座標が整形式でない場合、つまり、T1, T2 ... Tn
以外の型を持つ場合(T1, T2 ... Tn
はターゲット変数ハンドルのpos
の位置から始まる座標型です)。
-
permuteCoordinates
public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) 新しい座標が指定された座標と一致するように再配列することで、ターゲットのvarハンドルの座標値を適応させるvarハンドルを提供します。指定された配列によって並べ替えが制御されます。
#I
に着信座標の数(値はnewCoordinates.size()
)をコールし、#O
に送信座標の数(ターゲット変数ハンドルに関連付けられた座標の数)をコールします。 このとき、並べ替え配列の長さは#O
、各要素は#I
より小さい負でない数でなければいけません。#O
未満のすべてのN
について、N
番目の送信座標は、I
がreorder[N]
であるI
番目の受信座標から取得されます。座標値の変換は適用されません。
newCoordinates
によって決定される各受信座標の型は、ターゲット変数ハンドル内の対応する送信座標の型と同じである必要があります。並べ替え配列では、実際の入れ替えを指定する必要はありません。 入力座標は、そのインデックスが配列内に複数回出現する場合は複製され、インデックスが配列内に存在しない場合は入力座標が削除されます。
結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(
VarHandle.AccessMode
を参照してください)およびアトミック・アクセスが保証されます。- パラメータ:
target
- 座標が並べ替えられた後に呼び出すvarハンドルnewCoordinates
- 新しい座標型reorder
- 並べ替えを制御するインデックス配列- 戻り値:
- ターゲットのvarハンドルを呼び出す前に、着信座標値を再配置するアダプタのvarハンドル
- 例外:
IllegalArgumentException
- 索引配列の長さがターゲットのvarハンドルの座標数と等しくない場合、索引配列要素がnewCoordinates
の座標に対して有効な索引でない場合、またはターゲットのvarハンドルとnewCoordinates
の対応する座標タイプが同じでない場合。
-
collectCoordinates
public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) フィルタ(メソッド・ハンドル)を使用して座標値のサブシーケンスを前処理することで、ターゲット変数ハンドルを適応させます。 前処理された座標はフィルタ関数の結果(もしあれば)に置き換えられ、変更された(通常は短縮)座標リストでターゲット変数ハンドルが呼び出されます。R
がフィルタ(voidにはできません)の戻り型である場合、ターゲット変数ハンドルは、pos
の位置の座標として、フィルタに渡されない座標の前または後ろ(あるいはその両方)にR
型の値を受け入れる必要があります。 座標の順序は変更されず、フィルタから返される結果は、最初にアダプタに渡された座標のサブシーケンス全体を(順番)に置き換えます。フィルタの引数の型(もしあれば)は、調整後のvarハンドルの位置
pos
にあるターゲットvarハンドルのゼロまたは1つの座標型を置き換えます。 フィルタの戻り型は、pos
の位置にあるターゲット変数ハンドルの座標型と同じである必要があり、そのターゲット変数ハンドル座標はフィルタの戻り値によって提供されます。結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(
VarHandle.AccessMode
を参照してください)およびアトミック・アクセスが保証されます。- パラメータ:
target
- 座標がフィルタ処理された後に呼び出すvarハンドルpos
- フィルタ処理される座標の位置filter
- フィルタ・メソッド・ハンドル- 戻り値:
- ターゲットのvarハンドルを呼び出す前に、着信座標値をフィルタ処理するアダプタのvarハンドル
- 例外:
IllegalArgumentException
-filter
の戻り型がvoidの場合、またはターゲットのvarハンドルのpos
座標と同じでない場合、pos
が0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合、結果のvarハンドル型に「座標が多すぎます」が含まれる場合、またはfilter
がチェック例外をスローする場合。
-
dropCoordinates
ターゲットのvarハンドルに委譲する前にダミー座標を破棄するvarハンドルを返します。 その結果、結果のvarハンドルは、ターゲットのvarハンドルよりも座標型が多くなります。pos
引数の範囲はゼロからNです。ここで、Nはターゲットのvarハンドル座標型の引数です。pos
がゼロの場合、ダミー座標はターゲットの実引数の前に配置され、pos
がNの場合は後ろに配置されます。結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(
VarHandle.AccessMode
を参照してください)およびアトミック・アクセスが保証されます。- パラメータ:
target
- ダミー座標がドロップされた後に呼び出すvarハンドルpos
- (左端のゼロ)を削除する最初の座標の位置valueTypes
- ドロップする座標の型- 戻り値:
- ターゲットvarハンドルを呼び出す前にダミー座標をドロップするアダプタvarハンドル
- 例外:
IllegalArgumentException
-pos
が0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合。
-