Центр дистанционного обучения
Абстрактные типы данных (ADT)
Для чего нужно присваивание “elements[top] = null” в pop?
MyStack<String> stack = new ArrayStack<>(new String[10]); stack.push(“A”.repeat(1_000_000));
stack.pop();
//Без обнуления ссылка на строку из миллиона символов
//так и будет находиться в массиве до следующего push,
//и сборщик мусора не будет освобождать эту память,
//хотя она по сути уже не нужна
online.mirea.ru
Центр дистанционного обучения
Абстрактные типы данных (ADT)
Из-за ограничения на generics мы не можем вызвать new E[] в конструкторе ArrayStack, и вынуждены передавать массив извне. Это можно обойти с помощью некоторых хаков.
online.mirea.ru
Центр дистанционного обучения
Абстрактные типы данных (ADT)
public class ArrayStack2<E> implements MyStack<E> {
private final Object[] elements;
private int top = -1;
public ArrayStack2(int size) { this.elements = new Object[size];
}
@Override public E pop() {
if (isEmpty()) throw new IllegalStateException("Stack is empty: cannot pop"); E result = (E) elements[top];
elements[top] = null; top--;
return result;
}
}
online.mirea.ru
Центр дистанционного обучения
Абстрактные типы данных (ADT)
В общем случае эта строка:
E result = (E) elements[top]; // Object[] elements
может вызывать ClassCastException, поэтому компилятор выдает для нее предупреждение:
ArrayStack2.java uses unchecked or unsafe operations
Но в нашем случае мы можем гарантировать, что массив elements всегда содержит только элементы типа E, хотя он и объявлен как массив Object, так как мы помещаем в массив элементы только в методе push со значением типа E.
online.mirea.ru
Центр дистанционного обучения
Абстрактные типы данных (ADT)
Компилятор Java недостаточно умен, чтобы это понять. Если бы мы вызывали код “elements[0] = 42”, тогда компилятор был бы прав – наш код не работал бы с E, отличным от Integer.
Компилятор можно попросить не выдавать предупреждение:
@SuppressWarnings("unchecked") @Override
public E pop() {
if (isEmpty()) throw new IllegalStateException("Stack is empty: cannot pop"); E result = (E) elements[top];
elements[top] = null; top--;
return result;
}
При этом отсутствие ClassCastException гарантирует не
компилятор, а программист.
online.mirea.ru