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