具有初始化变量的NPE

ave*_*496 14 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;
    }
}
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)

spi*_*spi 28

子类之前的DefaultTableModel调用构造函数getRowCount有机会初始化其内容,从而导致NPE与您的实现.这是一个糟糕的基类设计,因为从构造函数中调用可覆盖的方法被认为是一种不好的做法,但是嘿,Swing API有很多这样的:)

参看 构造函数中的可覆盖方法调用有什么问题?


use*_*421 13

不要扩展DefaultTableModel,扩展AbstractTableModel.

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

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

public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
Run Code Online (Sandbox Code Playgroud)

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

另一种方法是实现TableModel,但是AbstractTableModel需要处理一些标准(讨厌的?)功能,比如维护监听器.

(不好的选择,只是检查null,但这可能会搞乱DefaultTableModel代码 - 不要这样做)