Java 如何在子类上下文中执行从超类继承的方法?

Java 如何在子类上下文中执行从超类继承的方法?,java,inheritance,scope,Java,Inheritance,Scope,我正在实现一个类似JPA的过程:表示一个表的所有类都必须是一个DBTable抽象类的子类,这个抽象类包含一个HashMap,它将列名(字符串)链接到java.lang.reflect.Field,我是通过调用super class构造函数中的getClass().getDeclaredFields()得到的,从子类构造函数调用。 这是有效的(我从子类中获得我想要的成员) 我想从ResultSet动态设置子类的这些成员,该子类将调用字段.set(这个,ResultSet.getXXX(column

我正在实现一个类似JPA的过程:表示一个表的所有类都必须是一个
DBTable
抽象类的子类,这个抽象类包含一个HashMap,它将列名(字符串)链接到
java.lang.reflect.Field
,我是通过调用super class构造函数中的
getClass().getDeclaredFields()
得到的,从子类构造函数调用。 这是有效的(我从子类中获得我想要的成员)

我想从
ResultSet
动态设置子类的这些成员,该子类将调用
字段.set(这个,ResultSet.getXXX(column))
,该方法最初作为助手在超类中实现,但是我得到了一个
java.lang.IllegalAccessException:classdbtable无法访问修改器为“protected”的MyTable类的成员

结果证明该方法是在超类上下文(抽象类!)中执行的:如果我在我的子类中复制/粘贴该方法,它工作正常

以下是一个片段:

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
}
公共抽象类DBTable{
公共数据库表(){
hm=新的HashMap();
对于(字段f:getClass().getDeclaredFields()){
hm.put(f.getAnnotation(Annot.class).value(),f);//“Annot”给出列名
}
}
受保护的布尔setFieldClass(字段f、结果集rs、整数iCol){
类类型=f.getType();
if(type==String.class){
f、 set(this,rs.getString(iCol));//IllegalAccessException
}
}
公共布尔读取(结果集rs){
ResultSetMetaData meta=rs.getMetaData();
for(int i=1;i
MyTable
对象调用的
read
方法继承自
DBTable
类,该类依次调用引发错误的
setFieldClass
方法。 如果我将
setFieldClass
方法从
DBTable
复制/粘贴到
MyTable
中,它将起作用,并将
dataStr
成员更改为public

我可以调用setter,而不是直接设置成员值,但希望避免这样做(我不确定子类是否会实现它,也不确定它们是否都提供相同的名称)


感谢您与我分享您的见解!:)

调用
Field.setAccessible(true)
之前调用
Field.set

调用
Field.setAccessible(true)
之前调用
Field.set

这很正常,无法构造抽象类。 那就不可能建造它了。 编写
公共类MyTable extensed DBTable
时,编译器将执行继承的方法。
不带super()的测试;我认为它可能会起作用。

这很正常,抽象类无法构造。 那就不可能建造它了。 编写
公共类MyTable extensed DBTable
时,编译器将执行继承的方法。
不带super()的测试;我认为它可能会起作用。

调用
super()
不会实例化
DBTable
对象(因为,正如您所说,它是抽象的,不能实例化),而是执行
DBTable()的代码。我需要它来遍历我的子类的所有字段:在本例中,
getClass()
方法返回类
MyTable
,而不是
DBTable
(这是我想要的),这意味着它是在
MyTable
上下文中执行的。但是,方法
setFieldClass()
似乎是在
DBTable
上下文中执行的,这会导致异常,因为它无法访问其子类的
受保护的
成员。我仍然不明白为什么…现在我知道了:因为代码是在类
字段
上下文中执行的(请参阅我的注释)。调用
super()
不会实例化
DBTable
对象(因为,正如您所说,它是抽象的,不能实例化),而是执行
DBTable()
的代码。我需要它来遍历我的子类的所有字段:在本例中,
getClass()
方法返回类
MyTable
,而不是
DBTable
(这是我想要的),这意味着它是在
MyTable
上下文中执行的。但是,方法
setFieldClass()
似乎是在
DBTable
上下文中执行的,这会导致异常,因为它无法访问其子类的
受保护的
成员。我仍然不明白为什么…现在我知道了:因为代码是在类
字段
上下文中执行的(请参阅我的注释)
不在子类上下文中执行,而是在
字段
上下文中执行,因为
Field.set
方法正在访问类成员。事实上,code
f.set(这是rs.getString(iCol))
不会在子类上下文中执行,而是在
字段
上下文中执行,因为
字段.set
方法正在访问类成员。