7

有効な Javaジェネリックの章UnaryFunctionで定義されているインターフェイスを考えてみましょう。

public interface UnaryFunction<T> {
T apply(T arg);
}

を返すための次のコードUnaryFunction

// Generic singleton factory pattern
private static UnaryFunction<Object> IDENTITY_FUNCTION = new UnaryFunction<Object>() {
  public Object apply(Object arg) { return arg; }
};

// IDENTITY_FUNCTION is stateless and its type parameter is
// unbounded so it's safe to share one instance across all types.
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> identityFunction() {
  return (UnaryFunction<T>) IDENTITY_FUNCTION;
}

のキャストが安全なのはなぜIDENTITY_FUNCTIONですか(UnaryFunction<T>)?

この本は、私が尋ねている質問についてこれを述べていますが、ここで論理に従うことはできません。applyID 操作を行う関数はどこで呼び出しているのでしょうか。何も変更せずに渡された同じオブジェクトを返すのはその関数であるため、私は混乱しています。

IDENTITY_FUNCTION のキャストは、 for everyではない ため(UnaryFunction<T>)、チェックされていないキャスト警告を生成します。しかし恒等関数は特別です: 引数を変更せずに返すので、 の値が何であれ、それを として使用しても型安全であることがわかっています。したがって、このキャストによって生成されるチェックされていないキャストの警告を自信を持って抑制することができます。これが完了すると、コードはエラーや警告なしでコンパイルされます。UnaryFunction<Object>UnaryFunction<T>TUnaryFunction<T>T

4

3 に答える 3

3

キャストは、アイデンティティ関数が最初に渡された正確なオブジェクトを返す場合にのみ安全です。Tそのため、実行時に、キャストに違反する可能性のあるジェネリック パラメーターの特殊化はありません。

別名、オブジェクトを独自のタイプとしてキャストしています。

于 2013-02-25T16:55:08.540 に答える
3

型消しあり

T apply(T arg);

実際には

Object apply(Object arg);

これからはアイデンティティー

Abc x = ...;
Abc y = IDENTITY.apply(x);

常に正しいと仮定することができます ( と同等ですy = x;)。

(非常に実用的です。)

于 2013-02-25T16:53:03.827 に答える
1

identityFunction() は単に関数自体を返し、さまざまなオブジェクトで使用されます。

以下は使用例です。

String result = identityFunction().apply("Hello");

型安全警告は重要です。IDENTITY_FUNCTION が実装されているため、関数が入力と同じ型を返すことをコンパイラが保証できないためです。次の代替実装を検討してください。

private static UnaryFunction<Object> CONST_FUNCTION = new UnaryFunction<Object>() {
    public Object apply(Object arg) { return "Default"; } 
};

この実装は常に文字列を返すため、汎用データ型の単項関数として返すのは明らかに安全ではありません。

私たちの場合 (IDENTITY_FUNCTION)、返された型が入力型と同じであることの証明は実装内にあります。同じインスタンスを返すため、同じ型であることが保証されます。タイプ セーフの警告を抑制する場合は、証明で正当化することをお勧めします。

于 2013-02-25T16:58:45.633 に答える