有人可以向我解释为什么我在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)
其他方法可以被覆盖以调整其行为,如isCellEditable或getColumnClass.如果数据被更改,fireXXX则应调用适当的方法,以便调用已注册的侦听器(例如,JTable使用该模型).
另一种方法是实现TableModel,但是AbstractTableModel需要处理一些标准(讨厌的?)功能,比如维护监听器.
(不好的选择,只是检查null,但这可能会搞乱DefaultTableModel代码 - 不要这样做)