[効果java]アイテム29|それならジェネリックタイプ
ジェネリッククラスをJENERICタイプに変更します。
public class ObjectStack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public ObjectStack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
上記のコード状態では、スタックから取り出したオブジェクトを変換する必要があり、実行時エラーが発生する可能性があります.だから、ジェニーンリックタイプのクラスに変えたほうがいいです.
通常クラスでJENICタイプクラスにするのは、タイプパラメータの追加が始まりです.通常、タイプ名として
E
が使用されます.
public class GenericStack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public GenericStack() {
this.elements = new E[DEFAULT_INITIAL_CAPACITY]; // 오류발생
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0) {
throw new EmptyStackException();
}
E result = elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
タイプパラメータエラーを解決する2つの方法
1.
E
配列を作成し、JENIC配列に変換されたJENIC配列の生成を禁止する制約を迂回します.[オブジェクト配列の作成時に配列を変換]
...
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public GenericStack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY]; // 경고 메시지 발생
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
...
// 비검사 형변환 경고 메시지 발생
Unchecked cast: 'java.lang.Object[]' to 'E[]
Object
配列がelements
フィールドに格納されると、クライアントに返されるか、他のメソッドに転送されません.private
方法によってアレイに格納される要素のタイプは、常にpush
である.E
非チェック変換警告の範囲を最小限に抑え、警告を非表示にします....
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
// 배열 elements는 push(E)로 넘어온 E인스턴스만 남는다.
// 타입 안정성을 보장하지만 이 배열의 런타임 타입은 Object[] 이다.
@SuppressWarnings("unchecked")
public GenericStack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY]; // 경고 메시지 발생
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
...
// 비검사 형변환 경고 메시지 발생
Unchecked cast: 'java.lang.Object[]' to 'E[]
@SuppressWarnings("unchecked")
フィールドのタイプをelements
からE[]
に変更する方法.[オブジェクト配列を保持しpop()を使用してシェイプに変換]
// 비검사 경고를 적절히 숨긴다.
public class GenericStack<E> {
private Object[] elements;
...
public GenericStack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0) {
throw new EmptyStackException();
}
// push에서 E 타입만 허용하므로 이 형변환은 안전하다.
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
...
}
2つの方法の長所と短所は、
Object[]
はE
ではなく(配列のコンパイル時間タイプとランタイムタイプが異なるため)、臀部汚染が開始される.整理する
実体化不可能なタイプを処理する過程でコンパイラの警告を迂回する矛盾が生じるが,JENNERICタイプが提供するタイプ安定性は極めて便利であるため,JENNERICを適切かつ積極的に使用する.
[Reference]
臀部汚染
Reference
この問題について([効果java]アイテム29|それならジェネリックタイプ), 我々は、より多くの情報をここで見つけました https://velog.io/@alkwen0996/이펙티브-자바-아이템29-이왕이면-제네릭-타입으로-만들라テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol