我正在实现一个类似JPA的进程:表示表的所有类都必须继承一个DBTable
抽象类,该类包含一个HashMap,它将列名(String)链接到调用{{java.lang.reflect.Field
的{{1}} 1:}在超类构造函数中,从子类构造函数调用。
这是有效的(我从子类中得到了我想要的成员)。
我想从getClass().getDeclaredFields()
动态设置子类的这些成员,它会在最初在超类中实现的方法中调用ResultSet
作为帮助器,但我得到{{1 }}
事实证明,该方法是在超类上下文(抽象类!)中执行的:如果我在子类中复制/粘贴该方法,它的工作正常。
这是一个片段:
Field.set(this, ResultSet.getXXX(column))
java.lang.IllegalAccessException: Class DBTable can not access a member of class MyTable with modifiers "protected"
对象上调用的public abstract class DBTable {
public DBTable() {
hm = new HashMap<String,Field>();
for (Field f : getClass().getDeclaredFields()) {
hm.put(f.getAnnotation(Annot.class).value(), f); // 'annot' gives the column name
}
}
protected boolean setFieldClass(Field f, ResultSet rs, int iCol) {
Class<?> type = f.getType();
if (type == String.class) {
f.set(this, rs.getString(iCol)); // IllegalAccessException
}
}
public boolean read(ResultSet rs) {
ResultSetMetaData meta = rs.getMetaData();
for (int i = 1; i < meta.getColumnCount(); i++) {
Field f = hm.get(meta.getColumnName(i));
setFieldClass(f, rs, i); // IllegalAccessException
}
}
public abstract someAbstractOtherMethod();
}
public class MyTable extends DBTable {
@Annot("DataCol") // Set the column name to "DataCol"
protected String dataStr;
public MyTable() {
super();
}
// 'dataStr' getter/setter
// 'someAbstractOtherMethod' implementation
}
public static void main(String[] args) {
MyTable mt = new MyTable();
ResultSet rs = ...; // Execute SELECT query returning a single row with a "DataCol" column containing a varchar(32)
mt.read(rs); // IllegalAccessException
}
方法继承自read
类,后者又调用引发错误的MyTable
方法。
如果我将DBTable
方法从setFieldClass
复制/粘贴到setFieldClass
,则可以正常工作,并将DBTable
成员更改为公开。
我可以调用一个setter而不是直接设置成员值,但是我希望避免这样做(我不确定子类是否会实现它,也不会给出相同的名称)。
感谢您与我分享您的见解! :)
答案 0 :(得分:2)
在致电Field.setAccessible(true)
之前致电Field.set
。
答案 1 :(得分:-1)
这是正常的,无法构建抽象类。
然后就不可能构建它。
编写public class MyTable extends DBTable
时,编译器会执行继承的方法。
测试没有 super(); 我认为它可能有用。