为什么用simpledateformat解析会抛出nullpointerexception? [复制]

问题描述 投票:0回答:1

此问题已经在这里有了答案:

我试图在将日期分配给构造函数中的实例变量之前验证日期的格式。每次,即使我每次尝试实例化一个对象时都为该字段提供一个值,它都会引发一个空指针异常。我认为问题必须出在parse语句上,但是我不明白为什么在那里会有空值。

此外,我想知道是否首先要在构造函数中验证日期是否是正确的做法。我应该有一种方法来代替吗?

非常感谢您的帮助。这是我第一次接触Java。

import java.text.*;

public class Photograph {
    private String caption;
    private final String filename;
    private String dateTaken;
    private int rating; //declares fields 

    public Photograph(String caption, String filename) {
        this.caption = caption;
        this.filename = filename;
        this.dateTaken = "1901-01-01";
        this.rating = 0;    //constructor 
    }

    public Photograph(String caption, String filename, String dateTaken,  
int rating) {
        this.caption = caption;
        this.filename = filename;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setLenient(false);

        try {
            sdf.parse(this.dateTaken);
            this.dateTaken = dateTaken;
        } catch (ParseException e) {
            this.dateTaken = "1901-01-01";
        }
    }

}

public static void main(String[] args) {
    // Testing


    //valid date
    Photograph test_photo1 = new Photograph("cap1", "pic1", "2017-09-30", 3);
    System.out.println(test_photo1.toString());
    Photograph test_photo2 = new Photograph("cap2", "pic2", "2017-12-25", 0);
    System.out.println(test_photo2.toString());
    Photograph test_photo3 = new Photograph("cap3", "pic3", "2018-14-25", 5);
    System.out.println(test_photo3.toString());
    Photograph test_photo4 = new Photograph("cap4", "pic4", "2018-03-27", 4);
    System.out.println(test_photo4.toString());
    Photograph test_photo5 = new Photograph("cap5", "pic5", "2018-03-29", 2);
    System.out.println(test_photo5.toString());
    Photograph test_photo6 = new Photograph("cap6", "pic6", "2018-10-21", 9);
    System.out.println(test_photo6.toString());
}
java nullpointerexception simpledateformat
1个回答
0
投票

对于您的错误,这很“简单”:

public Photograph(String caption, String filename, String dateTaken,  
int rating) {
  ..
        try {
            sdf.parse(this.dateTaken);
...
        } catch (ParseException e) {
   ...
        }
    }

this.dateTaken表达式解析为null,因为您想使用dateTaken(参数,而不是字段)。

[附带说明,我不会使用String来表示日期,而是使用LocalDateparse方法完全可以执行您要执行的操作,而LocalDate可以代替java.util.Date,并且不可变的。

  • 下面的示例使用了LocalDate,根据您的代码提供了三个构造函数。字段被设置为final,只有一个构造函数(最后一个)很重要。
  • 您可能可以通过在类中使用NO_DATE_TAKEN逻辑,或者更确切地说是null来避免存储空日期(Optional)。使用一个或另一个本身就是另一个问题。
    public class Photograph {
        private static final LocalDate NO_DATE_TAKEN = LocalDate.of(1901, Month.JANUARY, 01);

        private final String caption;
        private final final String filename;
        private final LocalDate dateTaken;
        private final int rating; //declares fields 

        public Photograph(String caption, String filename) {
          this(caption, filename, NO_DATE_TAKEN, 0);
        }

        public Photograph(String caption, String filename, String dateTaken,  
    int rating) {
          this(caption, filename, dateTaken == null ? NO_DATE_TAKEN:LocalDate.parse(dateTaken), rating);
        }

        public Photograph(String caption, String filename, LocalDate dateTaken,  
    int rating) {
          this.caption = caption;
          this.filename = filename;
          this.dateTaken = dateTaken == null ? NO_DATE_TAKEN:dateTaken;
          this.rating = rating;
        }

    }

我个人不使用字符串存储Date,并且由于我们有java.util.DateSimpleDateFormat做您正在尝试的确切操作,因此我不使用DateLocalDate来解析LocalDate.parse要做。

© www.soinside.com 2019 - 2024. All rights reserved.