2013-05-01 13 views
8

y割り当て行にタイプ変換の警告がある理由を誰もが説明できますか? xまたはzの割り当てには警告はありません。予期しないチェックされていない変換の警告

public class Entity<T> 
{ 
    @SuppressWarnings("unchecked") 
    public <TX> Entity<TX> typed(Class<TX> type) 
    { 
     return (Entity<TX>) this; 
    } 

    @SuppressWarnings("unchecked") 
    public static <TX> Entity<TX> typed(Entity<?> entity, Class<TX> type) 
    { 
     return (Entity<TX>) entity; 
    } 

    public static void main(final String[] args) 
    { 
     final Entity<?> a = new Entity<Integer>(); 
     final Entity b = (Entity) a; 

     final Entity<Integer> x = a.typed(Integer.class); 
     final Entity<Integer> y = b.typed(Integer.class); 
     final Entity<Integer> z = typed(b, Integer.class); 
    } 
} 
+2

あなたのエンティティ 'b'は、' a'からのキャストの後で型なしになるので、 'b.typed(Integer.class) 'で元に戻すと型なしになります。ジェネリック型はクラス型とは異なります。彼らは "ダウンキャスト"されても保持されません。 – Vulcan

答えて

6

b生型である、タイプEntityです。

public Entity typed(Class type) 

ですから、Entity<Integer>Entityから変換している。したがって、そのAPIは、次のようになります。コンパイラは、typeパラメータと返されるエンティティの種類との間の相関を失いました。したがって、何もチェックすることはできません。

final Entity<Integer> y = b.typed(String.class); 

を...、まだ、同じ警告が表示されます。

別の言い方をすると、あなたは使用することができます。 xまたはzで同じ変更を試みると、代わりにコンパイル時エラーが発生します。

編集:コメントに記載されているように、生のタイプを使用しているという事実は、ジェネリックの痕跡をすべて削除します。 JLS section 4.8から

:非ジェネリックレガシーコードとのインタフェースを容易にする

、型としてパラメータ化された型(§4.5)又は消去の消去(§4.6)を使用することが可能です要素型がパラメータ化された型である配列型(§10.1)。そのようなタイプは生のタイプと呼ばれます。

section 4.6

そして:

タイプ消失もないパラメータ化された型または型変数を持っていない署名のコンストラクタまたはメソッドのシグネチャ(8.4.2)をマッピングします。コンストラクタまたはメソッドシグネチャsの消去は、sと同じ名前とsで与えられたすべての仮パラメータ型の消去からなるシグネチャです。

+1

「型付き」メソッド自体がパラメータ化されていることに注意してください。型パラメータは2つあります。 –

+4

@ ConstantinKomissarchik:これは問題ではありません。生の型でメソッドを呼び出すと、すべてが消えてしまいます。 –

+0

コンパイラは、生の型でメソッドを呼び出すと言っているのを除いています。エンティティからエンティティへの割り当てで未確認の変換を実行していると言います。タイプがTXで完全に指定されている場合。 –

0

あなたは「ダウンキャスティング」して、bに割り当てるときに型識別子を削除します。 bは型指定されていないので、タイプが分からないため、型指定されていない変換警告が出ます。

final Entity<?> a = new Entity<Integer>(); 

aが入力されているので、メソッド呼び出しにも入力されるa.typed(Integer.class)です:

1
宣言から

typed(b, Integer.class)では、メソッドが汎用であるために機能します。

しかし

final Entity b = (Entity) a; 

であなたは(生型の代わりに、Entityのジェネリック版を使用してb用)ジェネリックオフになっているので、呼び出しb.typed(Integer.class)が型なしです。だからあなたは警告を受ける。

関連する問題