Java 我应该在类内部还是外部处理这些异常?

Java 我应该在类内部还是外部处理这些异常?,java,Java,我的Person类有两种不同的方法,一种是在创建Person对象之前处理可能的异常,另一种是在Person类中处理异常 方法1 import java.time.LocalDate; public class Person { String name; LocalDate birthDate; public Person(String name, LocalDate birthDate) { this.name = name; this

我的
Person
类有两种不同的方法,一种是在创建
Person
对象之前处理可能的异常,另一种是在
Person
类中处理异常

方法1

import java.time.LocalDate;

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, LocalDate birthDate) {
        this.name = name;
        this.birthDate = birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }
}



方法2

import java.time.LocalDate;

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, String birthDate) {
        this.name = name;
        this.setBirthDate(birthDate);
    }

    public void setBirthDate(String  birthDate) {
        String[] info = birthDate.split("-");

        // This may thrown DateTimeException, if someone gives an invalid year, month or day.
        birthDate = LocalDate.of(Integer.parseInt(info[0]), Integer.parseInt(info[1]), Integer.parseInt(info[2]));
        this.birthDate = birthDate;
    }
}


我应该期望所有
Person
客户机都导入
java.time.LocalDate
并自己创建日期,还是应该将这项工作封装在
Person
中,客户机只给出一个
字符串

我应该在其中处理异常还是在我称之为setter的任何地方处理异常?Java对此有一些规则吗

如果任何数据无效,最好在构造对象本身时抛出异常,以确保对象处于正确状态

此外,如果可以使用setter修改数据,则需要执行验证并引发异常,以确保对象再次处于正确状态

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, LocalDate birthDate) {
       //If input data is NOT valid,
       //throw new IllegalStateException("Invalid name and birthDate");
      //Now, if input data is valid, assign them to ref variables
      this.name = name;
      this.birthDate = birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
       //If input data is NOT valid,
       //throw new IllegalStateException("Invalid name and birthDate");
       this.birthDate = birthDate;
    }
}

当遇到这种问题时,你应该问自己两个问题

  • 这门课的目的是什么
  • 我在哪里可以处理异常
  • 对于这个例子,这个类是一个人的模型。POJO模型应该假设它们的依赖关系是正确的(
    LocalDate birthDate
    )。若要假设此模型的客户机输入正确,可以在其方法上引发异常

    public Person(String name, LocalDate birthDate) throws DateTimeException {
            this.name = name;
            this.birthDate = birthDate;
        }
    
    public void setBirthDate(LocalDate birthDate) throws DateTimeException {
        this.birthDate = birthDate;
    
    现在异常处理由这个Person类的客户机处理

    try{
        DateTimeFormatter germanFormatter = DateTimeFormatter.ofLocalizedDate(
                FormatStyle.MEDIUM).withLocale(Locale.GERMAN);
    
        LocalDate newYear = LocalDate.parse("01.01.2016", germanFormatter);
        Person person = new Person("Joe", newYear);
    
    }catch (DateTimeException e){
        // Do something about it
    }
    

    由于我不同意提供的任何一个答案,我将解释我将如何做

    首先,在描述问题时,用户输入的似乎是一个
    字符串
    ,它应该表示一个有效的
    LocalDate

    这里有一种常见的模式,叫做早扔,晚抓。由于您的
    人员的客户机正在处理用户输入,因此他们有第一次机会抛出/处理问题,并拥有最多可用信息(例如,他们可以尝试引导用户将其输入转换为有效的
    LocalDate

    为什么
    要关心将
    字符串
    转换为
    本地日期
    ?它应该只处理
    相关的状态和行为。它们也可以执行验证,但这些是特定于业务的检查,比如不允许在将来生日时构造
    对象(如果这没有意义,可能是那些)。在这种情况下,它绝对不应该抛出一个
    DateTimeException
    ,而应该抛出一个更合适的、用户定义的异常

    public Person(String name, LocalDate birthDate) throws InvalidBirthDateException {...}
    public void setBirthDate(LocalDate birthDate) throws InvalidBirthDateException {...}
    
    上述合同明确规定,
    Person
    类接受
    LocalDate
    生日,并让客户处理必要的数据转换,但它也指出,可能有一些日期不代表一个人的有效生日,在这种情况下,该方法将抛出一个自定义异常,客户端可以捕获并尝试修复该异常


    我的观点是:让客户机处理无效输入,因为他们可以修复它。异常被设计为在可能的情况下进行处理。想象一下你是如何在
    里面处理一个糟糕的约会的。最多返回一条错误消息,客户端仍然需要添加特定于用户输入的逻辑来捕获并尝试恢复。不要假设
    Person
    知道用户输入的来源(可能是命令行、GUI或文件)

    这些
    DateTimeException
    来自哪里?@sotiriosdelimanolisfrom LocalDate
    LocalDate
    是一种类型。它不会抛出异常。您显示的代码中没有任何部分可以抛出任何异常。我的错,如果提供的日期错误,则会抛出异常,一个月设置为13,例如
    LocalDate
    不能有一个值为13的月。构造
    LocalDate
    时将引发异常。这段代码中没有。对于无效的输入参数,
    IllegalArgumentException
    更适合并在语义上正确(从Javadoc:
    抛出以指示方法已传递非法或不适当的参数。
    )@dunni yes当输入的数据无效时可以使用此选项。当用户试图修改我们再次验证的日期时,我决定删除我的评论并发布我自己的解决方案。我理解为什么setter还需要验证它。我不明白在这种情况下如何定义无效的生日?在我看来,OP是在询问从哪里处理
    String
    LocalDate
    转换异常。既然已经有了
    LocalDate
    ,为什么还要抛出
    DateTimeException
    ?因为创建LocalDate可能会失败。尝试输入“01.012015”。或者任何其他错误的输入。什么?看看你的代码。当参数为
    LocalDate
    时,如何输入字符串?ctor没有理由抛出这种异常,因为在ctor中,生日已经是
    LocalDate
    try{
        DateTimeFormatter germanFormatter = DateTimeFormatter.ofLocalizedDate(
                FormatStyle.MEDIUM).withLocale(Locale.GERMAN);
    
        LocalDate newYear = LocalDate.parse("01.01.2016", germanFormatter);
        Person person = new Person("Joe", newYear);
    
    }catch (DateTimeException e){
        // Do something about it
    }
    
    public Person(String name, LocalDate birthDate) throws InvalidBirthDateException {...}
    public void setBirthDate(LocalDate birthDate) throws InvalidBirthDateException {...}