Unchecked cast в generic методе

353
11 января 2017, 00:52

Я хочу сделать универсальную фабрику для DAO-классов, чтобы при добавлении не приходилось писать новый метод "getNewEntityDao". Мне подсказали как правильно в данном случае использовать дженерики. И теперь это выглядит как-то так…

package com.employees.dao.impl;
import com.employees.dao.*;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
public class JDBCDaoFactoryImpl implements DaoFactory {
    private Map<Class, GenericDao> daoMap;
    private static final Logger logger = Logger.getLogger(JDBCDaoFactoryImpl.class);
    public JDBCDaoFactoryImpl() {
        daoMap = new HashMap<>();
        daoMap.put(CountryDao.class, CountryDaoImpl.getInstance());
        logger.info("Added dao for " + CountryDao.class.getSimpleName());
        ...
        daoMap.put(ParkingSpaceDao.class, ParkingSpaceDaoImpl.getInstance());
        logger.info("Added dao for " + ParkingSpaceDao.class.getSimpleName());
    }
    @Override
    public <T extends GenericDao> T getDao(Class<T> entityClass) {
        logger.info("Get dao for " + entityClass);
        if (!daoMap.containsKey(entityClass)) {
            logger.warn("Dao object for " + entityClass + " not found.");
            return null; //Maybe throwing exception be better
        }
        return (T)daoMap.get(entityClass);
    }
    public static void main(String[] args) {
        JDBCDaoFactoryImpl factory = new JDBCDaoFactoryImpl();
        CarDao dao = factory.getDao(CarDao.class);
        System.out.println();
        System.out.println(dao.getClass().getSimpleName());
    }
}

Но у меня возникло несколько вопросов: во-первых, в строке возврата из метода висит "Unchecked cast", и я никак не могу убрать этот warning (аннотация SuppressWarnings не в счет). А во-вторых, я не совсем понимаю чем является Т при вызове метода, к примеру как в main, при вызове с CountryDao.class чему равен Т в этом случаее.

Answer 1
  1. Так как у вас в Map хранятся GenericDao в качестве значений без преобразования не обойтись. Компилятор не может знать какой там тип и предупреждает, что могут быть ошибки преобразования.
  2. Т -это как параметр. Вы описываете общее поведение метода - получает параметр типа Class и возвращает значение типа T. T равен CarDao. Если "подставить" фактический тип вместо параметра, то получится:

    public CarDao getDao(Class<CarDao> entityClass)
    
READ ALSO
Hibernate many to many query not equal

Hibernate many to many query not equal

При таком запросе:

296
JasperReport не отображает поля типа java.lang.String

JasperReport не отображает поля типа java.lang.String

ЗдравствуйтеПроблема в JasperReports в WEB приложении : не отображаются в отчете значения полей типа java

317
Не могу динамично изменить файл з параметрами загрузки

Не могу динамично изменить файл з параметрами загрузки

Очень нужна помощьВ Java не долго, так что костылей полно, прошу сильно не пинать)

204