NPE具有初始化变量

时间:2018-08-17 07:13:23

标签: java swing

有人可以向我解释为什么我在getRowCount()方法中得到了NullPointerException吗?变量使用空的ArrayList初始化...

public class BeschriftungssetTableModel extends DefaultTableModel {

    private static final long serialVersionUID = -4980235976337188354L;

    private List<BeschriftungssetBean> data = new ArrayList<>();


    public void setData(List<BeschriftungssetBean> data) {
        this.data = data;
    }

    @Override
    public int getColumnCount() {
        return 1;
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public Object getValueAt(int row, int column) {
        return data.get(row).getBezeichnung();
    }

    @Override
    public String getColumnName(int column) {
        return "Bezeichnung";
    }

    public static void main(String[] args) {
        BeschriftungssetTableModel beschriftungssetTableModel = new BeschriftungssetTableModel();
        beschriftungssetTableModel.getRowCount();
    }
}



public class BeschriftungssetBean {
    private String objId;
    private String bezeichnung;

    public String getBezeichnung() {
        return bezeichnung;
    }

    public void setBezeichnung(String bezeichnung) {
        this.bezeichnung = bezeichnung;
    }

    public String getObjId() {
        return objId;
    }

    public void setObjId(String objId) {
        this.objId = objId;
    }
}

Exception in thread "main" java.lang.NullPointerException
at ch.aaa.xxx.yyy.gruppen.plugin.anzeige.beschriftungseinstellungen.BeschriftungssetTableModel.getRowCount(BeschriftungssetTableModel.java:36)
at javax.swing.table.DefaultTableModel.setDataVector(DefaultTableModel.java:224)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:124)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:106)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:86)
at ch.aaa.xxx.yyy.gruppen.plugin.anzeige.beschriftungseinstellungen.BeschriftungssetTableModel.<init>(BeschriftungssetTableModel.java:18)
at ch.aaa.xxx.yyy.gruppen.plugin.anzeige.beschriftungseinstellungen.BeschriftungssetTableModel.main(BeschriftungssetTableModel.java:50)

2 个答案:

答案 0 :(得分:28)

DefaultTableModel的构造方法在子类有机会初始化其内容之前调用getRowCount,从而导致NPE的产生。这是基类的不良设计,因为从构造函数内部调用可重写方法被认为是不良做法,但是,Swing API有很多这样的方法:)

Cf。 What's wrong with overridable method calls in constructors?

答案 1 :(得分:13)

请勿扩展DefaultTableModel,而应扩展AbstractTableModel

DefaultTableModel使用Vector来维护数据,并且不希望您在子类中拥有自己的数据。正如@spi所写,它正在调用getRowCount,该值被重写以返回尚未初始化的data的大小。

AbstractTableModel易于扩展(DefaultTableModel也很容易扩展),只需实现以下3种方法(已在问题代码中完成):

public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);

可以重写其他方法来调整其行为,例如isCellEditablegetColumnClass。如果更改了数据,则应调用适当的fireXXX方法,以便调用已注册的侦听器(例如,使用该模型的JTable)。

另一种方法是实现TableModel,但是AbstractTableModel会处理某些标准(讨厌的?)功能,例如维护侦听器。

不好的替代方法,只需检查null,但这可能会与DefaultTableModel代码混淆-不要这样做)

相关问题