2013-01-10 11 views
6

一般的なコードが少し見つかりましたが、実際にどのように動作するかはわかりませんでした。 これは、単純化された例ですが、これが有効なJavaコードであるかどうかまだ分かりません。あなたはTが何にもをバインドされていない書いたコードでこのJava関数はどこからジェネリック型を推測しますか?

public static void main(String[] args) { 
    System.out.print(get()); 
} 

public static <T> T get() 
{ 
    return (T) getObj(); 
} 

public static Object getObj() 
{ 
    return Boolean.FALSE; 
} 
+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7を参照してください。 – SLaks

+0

「Object」からのチェックされていないキャストに関する警告が表示されます'を' T 'にする。 – GriffeyDog

答えて

3

です。

ただし、型推論は戻り値が変数に割り当てられている場合にのみ戻り型に適用されます。そうでない場合 方法の結果は、それが、次に、割当て変換の対象となるコンテキストで発生した場合これはspec

で記述されている[...]

、常になる未解決の型パラメータObject
print(Object)オーバーロードがあるため、この例では問題なく動作します。一方

は、このコードを見て:コンパイラはprint()を見る前にObjectを返すようget()推測するため

print(get()); 

public void print(Boolean x) { } 

public <T> T get() { 
    return (T) Boolean.FALSE; 
} 

これは、コンパイルエラーになります。

+0

return文を編集することも、代入変換の対象となります。 Java 8では、型推論はより多くのコンテキスト情報を使用します。 – irreputable

1

。 Javaは、getメソッドを呼び出すたびにTに型を割り当て、戻ってくることを期待している型を調べますが、それはあなたが明示的にどの型を待っているのかを明示的に宣言した場合にのみ有効です。次の例を見てみましょう。一方

public static void jump(String a) { 
} 

public static <T> T get() { 
    return (T) null; 
} 

public static void main(String[] args) { 
    //This works quite well, generic parameter T is inferred to be String 
    String blah = get(); 
    jump(blah); 
} 

public static void jump(String a) { 
} 

public static <T> T get() { 
    return (T) null; 
} 

public static void main(String[] args) { 
    //This doesn't work, Java does not bind T to anything hence Object is used... and no jump for object is found 
    jump(get()); 
} 

少なくとも、これは型推論は、呼び出し場所に基づいて起こることは、Java 6の上にどのように動作するか

+0

'print(String)'ではなく 'print(Object)'を選択するというルールは何ですか? –

+1

それでは、私がそれを印刷しようとしなかった場合、それを真っ直ぐにしただけではどうでしょう。 public static void main(String [] args){ get(); }それはどこから推測されますか? – Deadron

+0

私は間違っていた、私はTが推測ではなく、何かに縛られていないと思う。それから、Javaが扱うことができる最も抽象的なものであるため、Objectが使用されます。私の答え – Claudio

関連する問題