2013-06-05 9 views
8

は私がインタビューテストを持っていたし、次のコードを見た:Java Genericsの値。 <SomeValue>

EDIT:

public class TestValue { 
    private Value<SomeValue> defaultValue; 

    @Test 
    public void Empty_Value_Has_No_Value() { 
     Assert.assertFalse(Value.<SomeValue> createEmptyValue() 
      .hasValue()); 
    } 

    @Test 
    public void Default_Value_IsEmpty() { 
     Assert.assertEquals(Value.<SomeValue> createEmptyValue(), 
      defaultValue); 
    } 

    @Test 
    public void Non_Empty_Value_Has_Value() { 
     Assert.assertTrue(new Value<SomeValue>(true, new SomeValue()) 
      .hasValue()); 
    } 
} 

私は見たことがなかったのJavaのジェネリックのような

Value.<SomeValue> 

テストが持つ値クラスを実装することです上記のユニットテストコード。私は(実装が必要)以下の値のメソッドシグネチャを把握しようとした

public interface Value<T> { 

    public boolean hasValue(); 
    public Value<T> createEmptyValue(); 
} 

いずれかが知っているが、助けてください?

はあなたに

EDITありがとう:

public class Value<T> { 

    public boolean hasValue(){} 
    public static <M> Value<M> createEmptyValue(){}; //need <M> 
} 

キーの構文は知って@marlon以下の回答によると、このようにする必要があります:

Value.<SomeValue> //ClassName.<Type>method 

はの静的メソッドを呼び出すための方法でありますパラメータ化された引数を持つクラス。

EDIT:@ snipes83によると、パラメータ化された引数を持つクラスの非静的メソッドを呼び出す構文です。

SomeObject.<Type>method 
+3

それはタイプミスだろうか? '値 .createEmptyValue()'が理にかなっています。 – Snps

+0

ホワイトボードコーディングですか? 多分、それは定義によって何でもかまいませんが、その型の値を提供することを意味するだけですが、型は本当に重要ではありません。 これは私がその場合に想定しているものです。 – clement

+0

ええ;好奇心をそそる自分。 –

答えて

6

Value.<SomeValue>これは、メソッドのジェネリックが表現される方法です。 GoogleのグアバのOptional例としてを使用して

Optional<String> email = Optional.<String>of(strEmail); 

は、インターフェースが静的メソッド(あなたのjavaの恥)を宣言することはできませんので、ちょうどstaticとしてあなたの方法を宣言し、インタフェースを忘れるGeneric Types - Invoking generic methods

を参照してください。このように:

class Value<T> { 

    public static <T> Value<T> createEmptyValue(){ 
     return null; 
    } 
} 
+0

上記のcreateEmptyValue()は静的であるべきですか? public staticのような値 createEmptyValue(); //コンパイルエラー:静的でない型への静的参照を作成できませんT – Eric

+1

@Eric:ほとんど、しかし 'public static の値 createEmptyValue()のように' 'に静的メソッドをパラメータ化します。 } '。コンパイラが指摘しているように、静的メソッドからクラスの非静的パラメータTを参照することはできません。 –

+0

@ Eric、Ryan Stewartコメントを反映するために私の答えを更新しました。 –

2

1)これはどのように一般的なメトですdsが呼び出されます。 Value.<SomeValue>http://docs.oracle.com/javase/tutorial/java/generics/methods.html

2)<SomeValue>任意ある>>参照。コンパイラはその型を推論できます。これはTypeInferenceと呼ばれます。参照してください>>http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

回答更新:Value.<SomeValue> createEmptyValue()が正しいとValue.<SomeValue>createEmptyValue()が右すぎる

3)。どちらの方法も合法です。ちょうどそれをテストした。前に気づかなかった以下の方法getEmptyListとクラスTest

+0

私はそれが空間で動作しようとしました。だから3)の両方でうまくいくはずですか? – Eric

+0

現在書かれているように、番号(3)に示されている2つの例の唯一の違いは空白です。あなたは仮定された違いについて詳しく説明できますか? – wchargin

+0

Awww、ちょうどそれをテストしました。それは動作します。やっぱり、気づかなかった。 –

3

ルック:それはタイプTの空List含むオ​​ブジェクトを返す

public class Test { 
    public <T> List<T> getEmptyList() { 
     return new ArrayList<T>(); 
    } 
} 

あなたはTest

このような
Test t = new Test(); 
List<Integer> list = t.getEmptyList(); 

を使用する場合は、型推論メカニズムは、変数の型に基づいて型パラメータを推測することができます。あなたがタイプList<Integer>の単一の引数を期待printList方法は、その後、型は任意の変数の型からinferedすることはできません、次の例のようにメソッド呼出し式内getEmptyListの戻り値を使用する必要がある場合は

次を使用して型を指定する必要があります。この場合
public void printList(List<Integer> list) { 
    for (int i : list) { 
     System.out.print(i); 
    } 
} 

printList(t.getEmptyList()); // This will FAIL. 

printList(t.<Integer>getEmptyList()); 
1

Valueは明らかに(Value<SomeValue>のインスタンス変数タイプに基づいて)入力された自身ですが、静的createEmptyValue()方法もありますタイプされた。

命名規則を遵守していれば、SomeValueは、Valueに拡張されます(または実装されています)。

が、私たち誰も正解が、Valueの署名のための可能性が高い可能性がある:

public class Value<T extend Value> { 
    public static <V extends Value> V createEmptyValue() { 
     // some impl 
    } 
}