JDBC中出现java.lang.NoSuchFieldException: bookName反射异常

版权声明:四川华迪信息技术有限公司java实训班乔二 https://blog.csdn.net/qxqx451/article/details/79421649

帮别人调试一个图书馆项目的时候实现一个查询图书的功能时报错 java.lang.NoSuchFieldException: bookName
没有这样的字段异常
代码如下
Dao层方法

@Override
    public List<Book> selectBook() {
        String sql = "select * from book";
        ArrayList<Object> paras = new ArrayList<>();

        return JDBCUtil.queryListExecute(sql, paras, Book.class);
    }

JBDCUtil工具类中方法

/**
     * 
     * 列表查询
     */
    public static<T> List<T> queryListExecute(String sql,ArrayList<Object> paras,Class<T> cls ){
        Connection conn = getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;
        T singleObject = null;
        int index = 1;
        List <T> list = new ArrayList<T>();
        try {
            pst = conn.prepareStatement(sql);
            if(paras !=null && paras.size()>0) {
                pst.clearParameters();
                for(int i = 0;i<paras.size();i++) {
                    pst.setObject(index++, paras.get(i));
                }   
            }
            rs = pst.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            while(rs.next()) {
                singleObject = cls.newInstance();
                for(int i = 0;i<columnCount;i++) {
                    String columnName = rsmd.getColumnName(i+1);
                    Object columdValue = rs.getObject(columnName);
                    Field field = cls.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(singleObject, columdValue);
                }
                list.add(singleObject);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return list;
    }

思考无果后只好去百度
得到的答案是一般是两个原因:
1,在创建数据库的时候可能存在复制粘贴导致数据库某一个字段属性多了空格
2,当属性为私有时获取Field用的方法是getField不是getDeclaredField。
(getField用于返回一个指定名称的属性,但是这个属性必须是公有的,这个属性可以在父类中定义。如果是私有属性或者是保护属性,那么都会抛出异常提示找不到这个属性
getDeclaredField获得在这个类型的声明中定义的指定名称的属性,这个属性必须是在这个类型的声明中定义,但可以使私有和保护的)

但是仔细排查数据库后发现数据库没有问题,在反射这块用的也是用的getDeclaredField方法。
最后终于在一个同学的火眼金睛下发现了问题所在

return JDBCUtil.queryListExecute(sql, paras, Book.class);

Dao层方法里调用queryListExecute(sql, paras, Book.class);方法时传入Book.class这个参数的作用是指定queryListExecute方法中的cls

Field field = cls.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(singleObject, columdValue);

问题就出现在传入的Book.class这个参数
书籍实体类的名字是BookEntity,实体类都错了,使用反射自然获取不到正确的字段

那么问题来了,既然这个Book类根本不存在为什么在写的时候没有报错
这里写图片描述
所以我传入的Book类是java.awt.print.Book
出现这样的问题有点巧合发现原因之后无比蛋疼

猜你喜欢

转载自blog.csdn.net/qxqx451/article/details/79421649
今日推荐