关于commons-dbutils使用时一个泛型问题的疑惑?

刚开始学习java,在使用commons-dbutils操作数据库,对其进一步封装的时候,有下面两种方式:

QueryRunner queryRunner = new QueryRunner();

// 方式1

public <T> T queryOne(Class<T> t,String sql, Object... params) throws SQLException {

try {

return queryRunner.query(connection,sql,new BeanHandler<>(t),params);

} finally {

// 省略代码...

}

}

// 方式2

public <T> T queryOne(T t,String sql, Object... params) throws SQLException {

try {

// idea为什么会在(Class<? extends T>) t.getClass())这个地方报一个警告:

// Unchecked cast: 'java.lang.Class<capture<? extends java.lang.Object>>' to 'java.lang.Class<? extends T>'

return queryRunner.query(connection,sql,new BeanHandler<T>((Class<? extends T>) t.getClass()),params);

} finally {

// 省略代码...

}

}

为什么在方式2会存在Unchecked cast警告?


回答:

这个异常提示是由于JAVA里的泛型擦除机制导致的。

在JAVA里,泛型类型经过编译实际上会被擦除,编译后JVM看到的只是原始类型或者是第一个边界的类型,也就是说:
方式1经过类型擦除后是这样的:

public Object queryOne(Class t, String sql, Object... params) throws SQLException {

try {

return queryRunner.query(connection, sql, new BeanHandler(t), params);

} finally {

// 省略代码...

}

}

方式2经过类型擦除后是这样的:

public Object queryOne(Object t, String sql, Object... params) throws SQLException {

try {

return queryRunner.query(connection, sql, new BeanHandler((Class) t.getClass()), params);

} finally {

// 省略代码...

}

}

方式二在运行时无法获取泛型具体类型,所以需要使用强制转换来将参数类型转换为 Class<? extends T>。如果传递的参数类型与实际类型不匹配,则可能会在运行时出现 ClassCastException 异常,存在一定的类型安全风险。
所以如果你能保证你传入的参数类型一定是正确的,可以使用@SuppressWarnings("unchecked")加在方法上来消除这条异常提示。

以上是 关于commons-dbutils使用时一个泛型问题的疑惑? 的全部内容, 来源链接: utcz.com/p/945212.html

回到顶部