Don't use raw type in Java Generic
7897 ワード
Effective Java Item 26
Raw Typeとは?
Raw Typeは過去のコードに存在し、Generic Typeを使用する Genericタイプの安定性に使用します. のコンパイル時間に、Generic Type情報が消去されます. までに、エラーはコンパイルから除外されます. パラメータを使用して要素のタイプを1つの範囲に制限したり、共通のパラメータ化をしたりしたくない場合は、WildCardタイプ( ワイルドカードを補強するには、
Raw type은 사용하지말라
についてのまとめです.Raw Typeとは?
まずJENICクラスまたはJENICインタフェースを定義しますタイプパラメータ(type parameter)がクラスとインタフェース宣言に使用される場合、JENICクラスまたはJENICインタフェースと呼ばれます.総称してジェニーンリックタイプ.
JENERICタイプが定義されている場合は、付属のRaw Typeも一緒に定義されます.ジェニーンリックタイプでタイプパラメータを全く使用しない場合を指します.List<E>
の元のタイプはList
です.ジェニーリックが来る前にコードと互換性があるように、私はまだそれを使用することができます.private final Collection stamps = ...;
ただし、Stampではなく上記のコードを使用すると、エラーが発生することなくCoinがコンパイルされて実行されます.(Genericのメリットは利用できません.)for (Iterator i = stamps.iterator(); i.hasNext();) {
Stamp stamp = (Stamp) i.next();
stamp.cancel();
}
上記のコードを変換するまで、エラーは見つかりません.エラーはできるだけコンパイル時に発見し、コンパイル時にすぐに発見することが望ましい.以上のように、Rawtypeを使用すると、実行時にのみエラーが検出されます.ClassCastException
が発生した場合は、Stampsへのコイン投入場所を検索するためにコード全体を参照する必要があります.
しかし、JENICを利用すれば、タイプ宣言自体がタイプの安定性を確保できる.private final Collection<Stamp> stamps = ...;
これで、Coinオブジェクトを切手に入れるコードがあれば、コンパイル時にエラーを認識できます.
要するに,Raw Typeを用いるとGenericによる安定性と表現力が失われる.互換性のため、まだ存在しますが、使用すべきではありません.
元のタイプのListを使用するよりも、List<Object>を使用します。
リストなどの元のタイプは使用しないでくださいが、List<Object>
などのすべてのクラスの親としてオブジェクトを使用することができます.違いは、List<Object>
がコンパイラにすべてのタイプを許可することを明確に示すことである.List
をパラメータとしてRawタイプを受け入れる方法に渡すことはできるが、List<String>
をパラメータとして渡すことはできない.これはジェニーリックのサブタイプルールに基づいています.List<Object>
は元のタイプのサブタイプであるが、List<Stirng>
のサブタイプではない.したがって、List<Object>
などのパラメトリックタイプを使用するのとは異なり、List<Object>
などの元のタイプを使用するとタイプが不安定になる.
要素が分からない場合は、Raw TypeではなくWildcardを使用します。
時々要素タイプを知らないRaw Typeを書きたい
2つのセット(Set)を受け取り、共通要素を返す方法を作成するとします.
次はgenericを使用する最初のユーザーが作成するコードです.static int numElementsInCommon(Set s1, Set s2) {
int result = 0;
for (Object o1: s1) {
if(s2.contains(o1))
result++;
}
return result;
}
Raw Typeを使用しているため、この方法は安全ではありません.コードを改善するには、非限定ワイルドカードタイプを使用することをお勧めします.static int numElementsInCommon(Set<?> s1, Set<?> s2) { ... }
上記の方法は最も一般的なパラメータ化設定タイプであり、任意のタイプを含んでもよい.List
とSet<?>
のタイプの違いは簡単で、Raw Typeはどんなタイプでもよいので、タイプ不変式を破壊しやすい.逆に、Set
には任意の要素を加えることはできません.(Nullを除く)オブジェクトのタイプは、取り出し時に全く不明です.これらの制限を解除するには、限定されたワイルドカードタイプを使用します.
Raw Typeは本当に使えないのですか?
個人的なコラボレーションの場合はコンシステンシは使わないほうがいいですが、Effective Javaには確かに役に立つ例があります.
Class LiteralはRaw Typeを使用する必要があります。
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a . and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
クラス文字は、クラス、インタフェース、配列、およびベースタイプ名を表す表現です.class literalのタイプはSet<?>
です.
class文字のパラメトリックタイプを無効にしました.Class
, List.class
Class Literalを単独で整理します
instanceofと併用する場合
実行時にJENICタイプ情報が消去されるため、instanceof演算子は非限定ワイルドカード以外のパラメトリックタイプに適用できません.
また,Raw Typeでも非限定ワイルドカードタイプでもinstanceofの動作は全く同じである.したがってinstanceof演算子を使用する場合、raw typeを使用するとより簡潔になります.
整理する
Raw Typeの概念を知って良いヒントを得た何気なくRaw Typeを乱用する可能性があります.これは意味のある定理で、いつ使うべきか、なぜ使うのかを知ることができます.
private final Collection stamps = ...;
for (Iterator i = stamps.iterator(); i.hasNext();) {
Stamp stamp = (Stamp) i.next();
stamp.cancel();
}
private final Collection<Stamp> stamps = ...;
リストなどの元のタイプは使用しないでくださいが、
List<Object>
などのすべてのクラスの親としてオブジェクトを使用することができます.違いは、List<Object>
がコンパイラにすべてのタイプを許可することを明確に示すことである.List
をパラメータとしてRawタイプを受け入れる方法に渡すことはできるが、List<String>
をパラメータとして渡すことはできない.これはジェニーリックのサブタイプルールに基づいています.List<Object>
は元のタイプのサブタイプであるが、List<Stirng>
のサブタイプではない.したがって、List<Object>
などのパラメトリックタイプを使用するのとは異なり、List<Object>
などの元のタイプを使用するとタイプが不安定になる.要素が分からない場合は、Raw TypeではなくWildcardを使用します。
時々要素タイプを知らないRaw Typeを書きたい
2つのセット(Set)を受け取り、共通要素を返す方法を作成するとします.
次はgenericを使用する最初のユーザーが作成するコードです.static int numElementsInCommon(Set s1, Set s2) {
int result = 0;
for (Object o1: s1) {
if(s2.contains(o1))
result++;
}
return result;
}
Raw Typeを使用しているため、この方法は安全ではありません.コードを改善するには、非限定ワイルドカードタイプを使用することをお勧めします.static int numElementsInCommon(Set<?> s1, Set<?> s2) { ... }
上記の方法は最も一般的なパラメータ化設定タイプであり、任意のタイプを含んでもよい.List
とSet<?>
のタイプの違いは簡単で、Raw Typeはどんなタイプでもよいので、タイプ不変式を破壊しやすい.逆に、Set
には任意の要素を加えることはできません.(Nullを除く)オブジェクトのタイプは、取り出し時に全く不明です.これらの制限を解除するには、限定されたワイルドカードタイプを使用します.
Raw Typeは本当に使えないのですか?
個人的なコラボレーションの場合はコンシステンシは使わないほうがいいですが、Effective Javaには確かに役に立つ例があります.
Class LiteralはRaw Typeを使用する必要があります。
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a . and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
クラス文字は、クラス、インタフェース、配列、およびベースタイプ名を表す表現です.class literalのタイプはSet<?>
です.
class文字のパラメトリックタイプを無効にしました.Class
, List.class
Class Literalを単独で整理します
instanceofと併用する場合
実行時にJENICタイプ情報が消去されるため、instanceof演算子は非限定ワイルドカード以外のパラメトリックタイプに適用できません.
また,Raw Typeでも非限定ワイルドカードタイプでもinstanceofの動作は全く同じである.したがってinstanceof演算子を使用する場合、raw typeを使用するとより簡潔になります.
整理する
Raw Typeの概念を知って良いヒントを得た何気なくRaw Typeを乱用する可能性があります.これは意味のある定理で、いつ使うべきか、なぜ使うのかを知ることができます.
static int numElementsInCommon(Set s1, Set s2) {
int result = 0;
for (Object o1: s1) {
if(s2.contains(o1))
result++;
}
return result;
}
static int numElementsInCommon(Set<?> s1, Set<?> s2) { ... }
個人的なコラボレーションの場合はコンシステンシは使わないほうがいいですが、Effective Javaには確かに役に立つ例があります.
Class LiteralはRaw Typeを使用する必要があります。
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a . and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
クラス文字は、クラス、インタフェース、配列、およびベースタイプ名を表す表現です.class literalのタイプは
Set<?>
です.class文字のパラメトリックタイプを無効にしました.
Class
, List.class
Class Literalを単独で整理しますinstanceofと併用する場合
実行時にJENICタイプ情報が消去されるため、instanceof演算子は非限定ワイルドカード以外のパラメトリックタイプに適用できません.
また,Raw Typeでも非限定ワイルドカードタイプでもinstanceofの動作は全く同じである.したがってinstanceof演算子を使用する場合、raw typeを使用するとより簡潔になります.
整理する
Raw Typeの概念を知って良いヒントを得た何気なくRaw Typeを乱用する可能性があります.これは意味のある定理で、いつ使うべきか、なぜ使うのかを知ることができます.
String[].class
)を使用します.?
のような境界ワイルドカードを使用することが望ましい.Reference
この問題について(Don't use raw type in Java Generic), 我々は、より多くの情報をここで見つけました https://velog.io/@jihoson94/Dont-use-raw-type-in-Java-Genericテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol