当前位置: 首页 > 知识库问答 >
问题:

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

艾嘉石
2023-06-17

刚开始学习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警告?

共有1个答案

李云
2023-06-17

这个异常提示是由于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")加在方法上来消除这条异常提示。

 类似资料:
  • 请问其中interface{ *int }是什么语法,看不懂为什么要这么声明

  • TypeScript 的 Truthiness narrowing 有如下介绍: all coerce to false, and other values get coerced to true. You can always coerce values to booleans by running them through the Boolean function, or by using t

  • Apache Commons DbUtils 库是一个非常小的类集,旨在简化JDBC调用处理而不会造成资源泄漏,并且代码更清晰。

  • 做作业的时候,算法的实现洪流填满了。我正在为这个指南编写一个程序:http://en.wikipedia.org/wiki/flood_fill。我有一些问题: 指定函数中的参数替换任何字符的颜色是否正常,我不知道这些坐标最初是什么颜色? 算法正确吗?例如,我在维基百科中编写了它,但我的程序的结果如下: 我的代码:

  • 我被泛型子类型搞糊涂了。 在Java中,如果类型是的子类型,则泛型类型和是不变的。例如,不是的子类型。 但是,在Scala中,如果类型是的子类型,则泛型类型和是协变的。那么Scala中泛型类的属性是什么而Java中没有呢?