Как выполнить методы, унаследованные от суперкласса в контексте подкласса? - PullRequest
1 голос
/ 10 февраля 2012

Я реализую JPA-подобный процесс: все классы, представляющие таблицу, должны быть подклассом DBTable абстрактного класса, который содержит HashMap, связывающий имена столбцов (String) с java.lang.reflect.Field Я получил от вызова getClass().getDeclaredFields() в суперконструктор класса, вызываемый из конструктора подкласса.Это работает (я получаю членов, которых я хочу из подкласса).

Я хочу динамически установить эти члены подкласса из ResultSet, который вызовет 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 в MyTable, он будет работать, как и изменение элемента dataStr на public.

Я мог бы вызвать установщик вместо прямой установки элементазначение, но хотел бы избежать этого (я не уверен, что подклассы будут реализовывать это, и при этом они не будут давать одинаковые имена).

Спасибо, что поделились со мной своими идеями!:)

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

позвоните Field.setAccessible(true) перед звонком Field.set.

0 голосов
/ 13 февраля 2012

Это нормально, абстрактный класс не может быть создан.Тогда это невозможно построить.Когда вы пишете public class MyTable extends DBTable, компилятор выполняет унаследованные методы.Тест без super (); Я думаю, что это может работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...