2

このコードの断片が ImmutableMap を型に解決できないという構文エラーを生成する理由に興味があります。

ImmutableMap<String, String> advice = ImmutableMap<String, String>.builder()
                    .put(KEY1, VAL1)
                    .put(KEY2, VAL2)
                    .build();

このコードは意図したとおりに機能しますが、次のようになります。

ImmutableMap<String, String> advice = ImmutableMap.<String, String>builder()
                    .put(KEY1, VAL1)
                    .put(KEY2, VAL2)
                    .build();

周期は私のメンタル モデルが本来あるべき方向に進んでおらず、誰かが周期の「方法側」にある理由を説明してくれることを期待していました。私はグアバの ImmutableMap を使用していますが、完全に関連しているとは思いません。それはジェネリックと関係があると思いますが、コンセプトが何と呼ばれるか分からないので、何がわからないのか、より良い答えを見つけるためにどのように検索すればよいのかわかりません。

編集:参考までに、ImmutableMapには次の行がありますbuilder()

public static <K, V> Builder<K, V> builder() {
    return new Builder<K, V>();
}
4

3 に答える 3

6

builder()は、定義されているクラスではなく、ジェネリック型が関連付けられている静的メソッドです。次のようになります。

public static <K,V> ImmutableMap.Builder<K,V> builder() { ... }

注:<K, V>ここでは、クラスのジェネリック型とは何の関係もありません。(これは一般的である必要はありません)

于 2012-08-31T14:28:47.323 に答える
1

Javaがジェネリックスを実装する方法のため、拡張ではなく型消去(キャスト)によって、実際には1つのImmutableMapクラスのみがロードされます。その静的なbuilder方法は、したがって、特定の一般的な過負荷に解決する必要があるものです。変数をコンパイラのシンタックスシュガーとして宣言すると、インスタンスメソッドがで呼び出されるたびに関連するオーバーロードが想定adviceます。ただし、静的メソッド呼び出しは個別に指定する必要があります。そのため、ジェネリックはドットのメソッド側に表示されます。ImmutableMap<String, String>adviceImmutableMap

これは、C#のように、拡張によってジェネリックを実装する言語では異なります。C#では、各ジェネリックマップタイプが個別のタイプとしてCLRに読み込まれるため、ImmutableMap<String, String>静的メソッドが異なる別のタイプになりますImmutableMap<Foo, Bar>

于 2012-08-31T14:28:15.670 に答える
0

この概念は少しあいまいなので、情報を見つけるのは困難です。Angelika Langer の素晴らしい Generics FAQ をしばらく検索して、それを見つける必要がありましたが、それについては知っていました...

とにかく、これは「明示的な型引数指定」と呼ばれ、ジェネリック メソッドの型引数を明示的に指定する場合に使用されます。通常は、コンパイラがコンテキストから推論できないため (たとえば、メソッド呼び出しをチェーンする場合)、または必要なためです。コンパイラがさまざまなオーバーロードから選択できるようにします。

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ402

型引数の推論の詳細:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ400

于 2012-09-02T09:48:37.647 に答える