我有一个类TableModelBase,它扩展了AbstractTableModel。在这里,我重写了getValueAt方法,以便它返回行类的getter结果。

TableModelBase.java

@Log
@AllArgsConstructor
public abstract class TableModelBase<T> extends AbstractTableModel{
    @NonNull private final String[] columns;
    @NonNull protected final transient List<T> rows;

    //...

    /**
     * Default getValue method.<br>
     * The row type fields must be in the same sequence that the columns.<br>
     * Getter methods must follow the getter convention.
     * @param rowIndex The row index.
     * @param columnIndex The column index matches the field index of the row type.
     * @return Object
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        final T row = rows.get(rowIndex);
        if(row.getClass().getDeclaredFields().length != getColumnCount()) {
            for (Field field : row.getClass().getDeclaredFields()) {
                System.out.println(field.getName());
            }
            log.severe("Fields number and table columns number are different in: " + row.getClass().getSimpleName());
            System.exit(1);
        }
        final Field field = row.getClass().getDeclaredFields()[columnIndex];

        String getter;
        if(field.getType().equals(boolean.class)) {
            getter = field.getName();
        }
        else {
            getter = "get" + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
        }

        try {
            Method method = row.getClass().getMethod(getter);
            return method.invoke(row);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            log.severe(e.getMessage());
            System.exit(1);
            return null;
        }
    }
}


我在包tablemodel中有一个测试类TableModelTest。在此程序包中还有类Data和DataModel。

资料库

@Value
class Data {
    String text = "text";
    boolean isSuccessful = true;
}


数据模型

class DataModel extends TableModelBase<Data> {
    DataModel() {
        super(new String[]{"Text", "Is Successful"}, new ArrayList<>());
        rows.add(new Data());
    }
}


TableModelBaseTest

public class TableModelBaseTest {
        @org.junit.Test
        public void getValueAt() {
            final DataModel dataModel = new DataModel();
            assertEquals("text",dataModel.getValueAt(0, 0));
            assertEquals(true, dataModel.getValueAt(0, 1));
        }
}


测试给出一个IllegalAccessException:


  com.dsidesoftware.tablemodel.TableModelBase类无法访问
  类tablemodel.Data的成员,带修饰符“ public”


吸气剂是公开的,为什么我不能使用它们?
奇怪的是,当我公开数据时,异常消失了。

有什么想法吗?

谢谢。

最佳答案

我怀疑这与Data类中的包私有的字段有关。如果您想避免此问题,只需在获得任何setAccessible(true);实例(即您的情况下为Field&Method)上调用java.lang.reflect.AccessibleObject即可。这将使对它们的get()调用忽略安全检查。

关于java - Method.invoke无法使用程序包专用类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45348323/

10-10 20:15