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 );
    }
}
4

3 に答える 3

6

b生の型Entityである type です。したがって、その API は次のようになります。

public Entity typed(Class type)

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

別の言い方をすれば、次のように使用できます。

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

...それでも同じ警告しか表示されません。xまたはで同じ変更を試みると、z代わりにコンパイル時エラーが発生します。

編集:コメントに記載されているように、生の型を使用しているという事実により、ジェネリックのすべての痕跡が削除されます。

JLS セクション 4.8から:

非ジェネリックなレガシー コードとのインターフェイスを容易にするために、パラメーター化された型 (§4.5) の消去 (§4.6) または要素型がパラメーター化された型である配列型の消去 (§10.1) を型として使用することができます。 . このようなタイプは raw タイプと呼ばれます。

そして、セクション 4.6で:

型消去は、コンストラクターまたはメソッドのシグネチャー (§8.4.2) を、パラメーター化された型または型変数を持たないシグネチャーにもマップします。コンストラクターまたはメソッド シグネチャ s の消去は、s と同じ名前で構成されるシグネチャであり、s で指定されたすべての仮パラメーター型の消去です。

于 2013-05-01T16:53:13.577 に答える
1

宣言から:

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

a型付けされているため、メソッド呼び出しa.typed( Integer.class )も型付けされています。

typed( b, Integer.class )メソッドがジェネリックであるため、機能します。

しかし、

final Entity b = (Entity) a;

ジェネリックをオフにしているため (ジェネリックbバージョンの代わりに生の型を使用するEntityため)、呼び出しb.typed( Integer.class )は型指定されていません。したがって、警告が表示されます。

于 2013-05-01T16:53:37.657 に答える
0

a を「ダウンキャスト」して、b に割り当てるときに型識別子を削除しています。b は型指定されていないため、型がわからないため、型指定なしの変換の警告が表示されます。

于 2013-05-01T16:53:24.640 に答える