此问题已经在这里有了答案:
我试图在将日期分配给构造函数中的实例变量之前验证日期的格式。每次,即使我每次尝试实例化一个对象时都为该字段提供一个值,它都会引发一个空指针异常。我认为问题必须出在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());
}
对于您的错误,这很“简单”:
public Photograph(String caption, String filename, String dateTaken,
int rating) {
..
try {
sdf.parse(this.dateTaken);
...
} catch (ParseException e) {
...
}
}
this.dateTaken
表达式解析为null
,因为您想使用dateTaken
(参数,而不是字段)。
[附带说明,我不会使用String
来表示日期,而是使用LocalDate
:parse方法完全可以执行您要执行的操作,而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.Date
和SimpleDateFormat
做您正在尝试的确切操作,因此我不使用Date
和LocalDate
来解析LocalDate.parse要做。