JAVA. Параметризация класса, появилась ошибка ClassCastException
Всем привет! Прошу помощи.
Абстрактный класс AbstractStorage переделываю в параметризованный абстрактный класс AbstractStorage<SK>. Соотвественно также методы делаю параметризованными. Тесты по дочернему классу ListStorage или любому другому ломаются с ошибкой
ClassCastException java.lang.String cannot be cast to java.lang.Integer
Понимаю, что где-то передаю неправильный тип, но как исправить пока не понимаю. Прошу помочь и объяснить где ошибка.
Родительский класс:
public abstract class AbstractStorage<SK> implements Storage {
private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());
protected abstract Integer findIndex(String uuid);
protected abstract void doUpdate(Resume resume, SK index);
protected abstract void doSave(Resume resume, SK index);
protected abstract Resume doGet(SK searchKey);
protected abstract void doDelete(SK searchKey);
protected abstract List<Resume> doGetList();
private SK doExistException(String uuid) {
Integer index = findIndex(uuid);
if (index < 0) {
LOG.warning("Резюме " + uuid + " не существует");
throw new NotExistStorageException(uuid);
}
return (SK) index;
}
private SK doNotExistException(String uuid) {
Integer index = findIndex(uuid);
if (index >= 0) {
LOG.warning("Резюме " + uuid + " уже существует");
throw new ExistStorageException(uuid);
}
return (SK) index;
}
public final void update(Resume resume) {
LOG.info("Update " + resume);
String uuid = resume.getUuid();
doUpdate(resume, doExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
}
public final void save(Resume resume) {
LOG.info("Save " + resume);
String uuid = resume.getUuid();
doSave(resume, doNotExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
}
public final Resume get(String uuid) {
LOG.info("Get " + uuid);
doExistException(uuid);
System.out.println("Резюме " + uuid + " найдено");
return doGet((SK) uuid);
}
public final void delete(String uuid) {
LOG.info("Delete " + uuid);
doExistException(uuid);
doDelete((SK) uuid);
System.out.println("Резюме " + uuid + " удалено.");
}
public final List<Resume> getAllSorted() {
List<Resume> list = doGetList();
list.sort(Resume::compareTo);
return list;
}
}
Наследник:
public class ListStorage extends AbstractStorage<Integer> {
private List<Resume> listStorage = new ArrayList<>();
@Override
public void clear() {
listStorage.clear();
}
@Override
public List<Resume> doGetList() {
return listStorage;
}
@Override
public void doUpdate(Resume resume, Integer index) {
listStorage.set(index, resume);
}
@Override
public void doSave(Resume resume, Integer index) {
listStorage.add(resume);
}
@Override
public Resume doGet(Integer searchKey) {
//int index = findIndex(searchKey);
//return listStorage.get(index);
return listStorage.get(searchKey);
}
@Override
public void doDelete(Integer searchKey) {
//int index = findIndex(searchKey);
//listStorage.remove(index);
listStorage.remove(searchKey);
}
@Override
public int size() {
return listStorage.size();
}
@Override
protected Integer findIndex(String uuid) {
for (int i = 0; i < listStorage.size(); i++) {
if (listStorage.get(i).getUuid().equals(uuid)) {
return i;
}
}
return -1;
}
}
Ответы (1 шт):
Если честно не до конца понимаю зачем Вам вообще параметризация. uuid - строка, по которой мы каждый раз находим индекс, который всегда имеет тип Integer и проверяем либо он есть, либо его нет. При необходимости кидаем исключение.
На мой взгляд параметризация не нужна:
public abstract class AbstractStorage implements Storage {
private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());
protected abstract Integer findIndex(String uuid);
protected abstract void doUpdate(Resume resume, Integer index);
protected abstract void doSave(Resume resume, Integer index);
protected abstract Resume doGet(Integer searchKey);
protected abstract void doDelete(Integer searchKey);
protected abstract List<Resume> doGetList();
private Integer doExistException(String uuid) {
Integer index = findIndex(uuid);
if (index < 0) {
LOG.warning("Резюме " + uuid + " не существует");
throw new NotExistStorageException(uuid);
}
return index;
}
private Integer doNotExistException(String uuid) {
Integer index = findIndex(uuid);
if (index >= 0) {
LOG.warning("Резюме " + uuid + " уже существует");
throw new ExistStorageException(uuid);
}
return index;
}
public final void update(Resume resume) {
LOG.info("Update " + resume);
String uuid = resume.getUuid();
doUpdate(resume, doExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
}
public final void save(Resume resume) {
LOG.info("Save " + resume);
String uuid = resume.getUuid();
doSave(resume, doNotExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
}
public final Resume get(String uuid) {
LOG.info("Get " + uuid);
System.out.println("Резюме " + uuid + " найдено");
return doGet(doExistException(uuid));
}
public final void delete(String uuid) {
LOG.info("Delete " + uuid);
doDelete(doExistException(uuid));
System.out.println("Резюме " + uuid + " удалено.");
}
public final List<Resume> getAllSorted() {
List<Resume> list = doGetList();
list.sort(Resume::compareTo);
return list;
}
}
Думаю, что можно изменить родительский класс так:
public abstract class AbstractStorage<R, U> implements Storage<R, U> {
private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());
protected abstract Integer findIndex(U uuid);
protected abstract void doUpdate(R resume, Integer index);
protected abstract void doSave(R resume, Integer index);
protected abstract R doGet(Integer searchKey);
protected abstract void doDelete(Integer searchKey);
protected abstract List<R> doGetList();
private Integer doExistException(U uuid) {
Integer index = findIndex(uuid);
if (index < 0) {
LOG.warning("Резюме " + uuid + " не существует");
throw new NotExistStorageException(uuid);
}
return index;
}
private Integer doNotExistException(U uuid) {
Integer index = findIndex(uuid);
if (index >= 0) {
LOG.warning("Резюме " + uuid + " уже существует");
throw new ExistStorageException(uuid);
}
return index;
}
public final void update(R resume) {
LOG.info("Update " + resume);
U uuid = resume.getUuid();
doUpdate(resume, doExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
}
public final void save(R resume) {
LOG.info("Save " + resume);
U uuid = resume.getUuid();
doSave(resume, doNotExistException(uuid));
System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
}
public final R get(U uuid) {
LOG.info("Get " + uuid);
System.out.println("Резюме " + uuid + " найдено");
return doGet(doExistException(uuid));
}
public final void delete(U uuid) {
LOG.info("Delete " + uuid);
doDelete(doExistException(uuid));
System.out.println("Резюме " + uuid + " удалено.");
}
public final List<R> getAllSorted() {
List<R> list = doGetList();
list.sort(R::compareTo);
return list;
}
}
И соответственно дочерний класс:
public class ListStorage extends AbstractStorage<Resume, String> {
private final List<Resume> listStorage = new ArrayList<>();
...
}
