簡體   English   中英

反射:拋出java.lang.NullPointerException

[英]Reflection: Throws java.lang.NullPointerException

1.for (Field field : fields) {
2.    if (p.contains(field.getName())) {
3.        if(field.getType().toString().split("[.]")[2].equals("String"))
4.            callableStatement.setString(field.getName(), field.get(obj).toString());
5.        else if(field.getType().toString().split("[.]")[2].equals("Integer"))
6.            callableStatement.setInt(field.getName(), (int)field.get(obj));
7.        System.out.println(field.get(obj).toString());
8.    }
9.}

這是我的代碼。 使用反射,我從類對象中獲取數據,並在上述循環中,為過程輸入設置了參數。 但是,它保存一些整數值,並在第7行上拋出java.lang.NullPointerException

這些值被接受:

this.DI_StDate = Common.getDateStamp(date); // Integer
this.DI_StTime = Common.getTimeStamp(date); // Integer

從Common.java

public static Integer getDateStamp(Date d) {
    return Integer.parseInt(requiredDate.format(d));
}

public static Integer getTimeStamp(Date d) {
    return Integer.parseInt(requiredTime.format(d));
}

這些引發異常:

this.FileOpsId = new Integer(1);            // Integer
this.FileTypeOpsId = 1;                     // Integer

請建議我要去哪里錯了。

這些是我的班級成員:

public class DIConnect {
    public Integer PROC_ID;
    public String APIKey;
    public String Username;
    public String pwd;
    public String StreamKey;

    public Integer DI_StDate;
    public Integer DI_StTime;

    public String FileNamePath;
    public Integer FileOpsTypeId;
    public String ConfigLabel;
    public Integer FileOpsId;

    public Integer End_Date;
    public Integer End_Time;

    public DIConnect(String FileNamePath, String ConfigLabel, Integer FileOpsTypeId, Integer StartDate, Integer StartTime) {
        this.FileNamePath = FileNamePath;
        this.ConfigLabel = ConfigLabel;
        this.FileOpsTypeId = FileOpsTypeId;
        this.DI_StDate = StartDate; // accepted
        this.DI_StTime = StartTime; // accepted
        this.FileOpsId = new Integer(1); // NOT ACCEPTED
    }
}

這是main()方法中的調用。

DIConnect DIC = new DIConnect(filePath, "File", 1, Common.getDateStamp(date), Common.getTimeStamp(date));
DIC.InsertFileOperation();

DIConnect.java:

public Integer InsertFileOperation() {
        String[] params = {"FileNamePath", "FileOpsId", "ConfigLabel", "DI_StDate", "DI_StTime"};
        DatabaseOperation db = new DatabaseOperation();
        if(db.openConnection()) {
            this.PROC_ID = db.executeProcedure("sp_InsertIntoFileOpsMaster", params, this);
            db.closeConnection();
        }
        return this.PROC_ID;
    }

Database.java

public Integer executeProcedure(String proc, String[] params, Object obj) {
        int Id = 0;
        try {
            String paramString = StringUtils.repeat("?, ", params.length + 1).trim();
            paramString = paramString.substring(0, paramString.length() - 1);
            proc = "{CALL " + proc + "(" + paramString + ")}";
            callableStatement = conn.prepareCall(proc);

            Class cls = obj.getClass();
            Field[] fields = cls.getFields();
            List<String> p = Arrays.asList(params);

            for (Field field : fields) {
                if (p.contains(field.getName())) {
                    if(field.getType().toString().split("[.]")[2].equals("String"))
                        callableStatement.setString(field.getName(), field.get(obj).toString());
                    else if(field.getType().toString().split("[.]")[2].equals("Integer"))
                        callableStatement.setInt(field.getName(), (int)field.get(obj));
                    System.out.println(field);                        
//                    System.out.println(field.get(obj).toString());
                }
            }
            callableStatement.registerOutParameter("Id",java.sql.Types.INTEGER);
            callableStatement.executeUpdate();
            Id = callableStatement.getInt("Id");

        } catch (SQLException | IllegalArgumentException | IllegalAccessException ex) {
            Logger.getLogger(DatabaseOperation.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex){
          System.out.println(ex.getMessage());
        } finally {
            return Id;
        }
    }

OUTPUT

public java.lang.Integer airteldemo.DIConnect.DI_StDate
public java.lang.Integer airteldemo.DIConnect.DI_StTime
public java.lang.String airteldemo.DIConnect.FileNamePath
public java.lang.String airteldemo.DIConnect.ConfigLabel
null

正如我猜到的field.get(obj) (有時)返回null所以您應該檢查它是否為null或以某種方式(取決於代碼的邏輯)不允許它變為null

鑒於您所提供的信息,我將此作為答復原因發布,我們只能告訴您問題出在哪里,而不是問題出在哪里。

您的代碼有幾個問題。


首先,字段在Java中可以為空值。 如果使用的是Object類型的參數, Object需要接受它並將null值映射到SQL值,也許是基於有關數據庫列類型的推理即可。

代替使用field.get(obj).toString()用於null字段值的field.get(obj).toString() ,而應使用String.valueOf(field.get(obj))


第二

else if(field.getType().toString().split("[.]")[2].equals("Integer"))

之所以被破壞是因為它假定java.lang.Integer因此可能會因ClassCastException而失敗;不是null安全的,因為(Integer) null與任何int值都不對應;當field.getType()類似於時,它可能因IndexOutOfBoundsException而失敗shortpackage.Integer

相反做

Integer.class.equals(field.getType()) || Integer.TYPE.equals(field.getType())

Integer.TYPEint基本類型的偽類。


第三,您似乎正在編寫自己的數據庫抽象層。 那里有很多ORB應該為您做。 我鼓勵您改用其中之一。

我發現了錯誤。 callablestatement獲取被調用過程的簽名。 這些參數應作為區分大小寫的參數傳遞。 我的過程將它們接收為FileOpsTypeID並且正在傳遞FileOpsTypeId 更改大小寫使其起作用。

回復較晚,抱歉。 同樣抱歉,我沒有提供完整的詳細信息(過程)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM