2016-07-04 8 views
2

私はジェネリックに新しいです入力すると、この回答を見ていた:それは完璧に動作キャストは、java

https://stackoverflow.com/a/17165079/1632141

、しかし私は、コードのこの部分がどのように動作するか理解できませんでした。

public T calories(int val) { 
    calories = val; 
    return (T) this; 
} 

NutritionFactsの内部クラスです。

ここでキャストはどのように機能しますか?純粋なスーパークラスオブジェクトをサブクラス化してキャストしているので、ここではjava.lang.ClassCastExceptionが必要です。

+1

"純粋なスーパークラスオブジェクト"とはどういう意味ですか?とにかく 'this'は常に' T'型になります。 –

+0

コードは 'public static class(GMOFacts。)のコンテキストで実行されます。BuilderはNutritionFacts.Builder <(GMOFacts。Builder)を拡張します。 「T」はそれを法的なキャストにするビルダー自身のタイプです。また、コードがスーパークラスで宣言されていても、 'this'はスーパークラス型ではありません。 'this'は常に具体的なランタイム(サブクラス)型です。 – zapl

+1

@LouisWasserman:そうではありません。 'this'は' T'型ではない可能性があります。 – newacct

答えて

2

は、実際にその答えに問題があります:

public static class Builder<T extends Builder> {... 

タイプTタイプです。それは次のようになります。それは自分自身を拡張しているため、型を参照自己と呼ばれる

public static class Builder<T extends Builder<T>> {... 

これは、典型的には、このように使われています:

public class SubBuilder extends Builder<SubBuilder> {... 

その場合には、タイプは、サブクラス自体のタイプがあります。

Builderの別のサブクラスを型としてコーディングすることはできますが、それは特に有用ではありません。

+0

ありがとう..助けて。 – starkk92

+0

私は 'T'が*サブタイプ*自体の型であると言うことを意味しました – Bohemian

+0

はい。それを得ました。ありがとう – starkk92

-1

スーパークラスオブジェクトをキャストしてそこにサブクラス化していません。とにかくGMOFacts.Builderオブジェクトへ

public GMOFacts.Builder calories(int val) { 
     calories = val; 
     return (GMOFacts.Builder) this; 
    } 

そしてthis基準点、それは有効なタイプのキャストだ:GMOFacts.Builderオブジェクトの場合、calories方法は、このような何かを消去タイプになります。

+1

タイプ消去されたコードが有効であるという理由だけで、ジェネリックメソッドがタイプセーフであるとは限りません。 – newacct

+0

@newacct申し訳ありませんが、わかりませんでした。あなたはこの特定の方法、または一般的なすべての一般的な方法について話していますか?どうしたらいいですか? –

+1

私はメソッド ' T foo(Object x){return(T)x; } 'も消去されたときに有効なキャストを持ちますが、明らかに型保証されていません。メソッド自体の消去されたコードに失敗するキャストが含まれていないという事実は、ジェネリックな戻り値の型はキャストを呼び出し元のコードに挿入して結果をキャストするため、ジェネリックメソッドが型セーフであることを意味しません。失敗する可能性があります。 – newacct

関連する問題