Исключение java.lang.ClassCastException возникает при попытке приведения объекта к подклассу, экземпляром которого он не является.
Например:
1 2 3 4 5 6 7 |
public class Main { public static void main(String[] args) { Object obj = new java.util.Date(); Integer int1 = (Integer) obj; } } |
Этот код при выполнении бросит исключение:
1 2 |
Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.Integer at Main.main(Main.java:5) |
Но бывает такая странная ситуация, когда исключение возникает при попытке преобразовать к классу, которым объект собственно и является. Например:
1 |
java.lang.ClassCastException: org.postgresql.util.PGInterval cannot be cast to org.postgresql.util.PGInterval |
На первый взгляд кажется, что это абсурд. Как это так, что нельзя привести класс к самому себе? Но такая ситуация вполне возможна. Она может возникнуть в случаях, когда у вас есть два одинаковых класса, но загруженных разными ClassLoader -ами. А это возможно, например, при разработке под WEB (J2EE, Spring Framework и т. д.). У меня такая ситуация возникла в случае, когда jar-ник с драйвером PostgreSQL был подключен два раза: один раз в war-файле, второй раз он был в каталоге lib у Apache Tomcat. По идее драйвер должен лежать в каталоге lib. Но проект начинал свой путь ещё до меня. Я решил в этом случае не использовать org.postgresql.util.PGInterval напрямую, а использовать Object и обращаться к методам через Reflection.
Получилось примерно вот так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
// ... ещё код return getJdbcTemplate().query( "select month_work_out, ... дальше SQL", new Object[] {/* параметры */ }, new RowMapper<FactAttendanceContainer>() { private long pgIntervalToMillis(Object pgInterval) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // Я задействовал только часы и минуты, // потому что в моём случае других полей не было. Method methodGetHours = pgInterval.getClass() .getMethod("getHours"); Method methodGetMinutes = pgInterval.getClass() .getMethod("getMinutes"); return (int) methodGetHours.invoke(pgInterval) * 60 * 60 * 1000 + (int) methodGetMinutes.invoke(pgInterval) * 60 * 1000; } @Override public FactAttendanceContainer mapRow(ResultSet rs, int rowNum) throws SQLException { try { // ... ещё код Object monthWork = rs.getObject("month_work_out"); Long monthWorkMillis = pgIntervalToMillis(monthWork); // дальше работаем уже с monthWorkMillis, где содержатся миллисекунды. // ... ещё код } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { LOG.error("FactAttendanceContainerMaping failed", e); throw new SQLException("factAttendanceContainerMapping failed."); } } }); // ... ещё код |