我应该如何处理从构造函数中抛出的异常

huangapple go评论64阅读模式
英文:

How should I handle exceptions thrown from the constructor

问题

我遇到了这个问题:

我正在创建一个对象,假设叫做 Person;

public class Person
{
    public Person(String name, int age)
    {
        if (age < 0)
        {
            throw new AgeException("年龄不能小于0");
        }
    }
}

每次初始化这个对象,我都需要处理一个 try-catch 块。这对我来说似乎有点不对,就像这样:

public static void main(String[] args)
{
    try
    {
        Person p = new Person("SwagiWagi", 18);
    }
    catch (AgeException ex)
    {
        int age = -18;
        
        if (age < 0)
        {
            age = 18;
        }
        
        try
        {
            Person p = new Person("SwagiWagi", 18);
        }
        catch (AgeException ex)
        {
           System.out.println("这看起来不对。");
        }
    }
}

这看起来不对,代码混乱且不清晰。

我应该怎么做?

英文:

I have come across this problem:

I am making an object, let's say, Person;

public class Person
{
    public Person(String name, int age)
    {
        if (age &lt; 0)
        {
            throw new AgeException(&quot;Age can not be lesser than 0&quot;);
        }
    }
}

Every initialization of the object means that I would have to deal with a try-catch block.
Seems kind of wrong to me, like:

public static main(String[] args)
{
    try
    {
        Person p = new Person(&quot;SwagiWagi&quot;, 18);
    }
    catch (AgeException ex)
    {
        int age = -18;
        
        if (age &lt; 0)
        {
            age = 18;
        }
        
        try
        {
            Person p = new Person(&quot;SwagiWagi&quot;, 18);
        }
        catch (AgeException ex)
        {
           System.out.println(&quot;This does not look right.&quot;);
        }
    }
}

This doesn't seem right, it's messy and unclear code.

What should I do?

答案1

得分: 0

是的,在我看来,过多地抛出和捕获异常会显得混乱。

相反,尝试一种不需要抛出异常的方法。

Scanner sc = new Scanner(System.in);
        
int age = sc.nextInt();
while (age < 0) {
    System.out.println("输入的年龄小于0。请重新输入。");
    age = sc.nextInt();
}

Person p = new Person("SwagiWagi", age);

在这种情况下,你将始终拥有一个正数年龄。

注意: 输入的内容应该是一个数字,否则.nextInt()会抛出异常,你需要处理这种情况。

英文:

Yes, in my opinion, throwing and catching too many exceptions is messy.

Instead, try an approach without having to throw exceptions at all.

Scanner sc = new Scanner(System.in);
    
int age = sc.nextInt();
while (age &lt; 0) {
    System.out.println(&quot;Age entered is less than 0. Please enter again.&quot;);
    age = sc.nextInt();
}

Person p = new Person(&quot;SwagiWagi&quot;, age);

You will always have a positive age in this case.

Note: The input entered should be a number or .nextInt() will throw an exception, which is something you will have to handle.

答案2

得分: 0

有些时候,你应该问问自己:在哪个时候程序应该崩溃,而不是试图修复问题?有时候,如果关键参数具有无效值,程序最好直接终止,因为它无法正常运行。

你可以简单地声明,主方法抛出一个 AgeException 异常,但程序仍然会崩溃,因为任何未处理的异常都会终止程序。如果你想确保程序继续运行,你必须处理所有声明的异常。

此外,你在这里做的事情在我看来是非常错误的:

public static main(String[] args)
{
    try
    {
        Person p = new Person("SwagiWagi", 18);
    }
    catch (AgeException ex)
    {
        int age = -18;

        if (age < 0)
        {
            age = 18;
        }

        try
        {
            Person p = new Person("SwagiWagi", 18);
        }
        catch (AgeException ex)
        {
           System.out.println("This does not look right.");
        }
    }
}

在第一个 try 块中,你想捕获来自用户或为 Person 对象提供参数的任何错误输入。在 catch 块中,你试图“纠正”该输入,并使用另一个 try-catch 块为相同的异常检查它。

最初传递错误参数的任何内容应该在第一时间就做正确。处理异常应该更像是在运行时检测问题的一种方式,而不是修复问题。

如果有一种方法可以简单地纠正问题,比如要求用户重新输入正确的值,当然可以这样做,但是可以在没有异常的情况下完成。如果不可能这样做,比如参数是由一些其他程序或线程提供的,你无法控制,那么程序应该崩溃。

英文:

At some point you should ask yourself: At which point SHOULD the program crash and not try to fix the problems? Sometimes it's just better if the program terminates because it can't properly run if a critical parameter has an invalid value.

You could simply declare, that the main-method throws an AgeException, but the program would still crash, because any unhandled exception terminates the program. If you want to make sure the program keeps running, you must handle all declared exceptions.

Also, what you are doing here seems very wrong to me:

public static main(String[] args)
{
    try
    {
        Person p = new Person(&quot;SwagiWagi&quot;, 18);
    }
    catch (AgeException ex)
    {
        int age = -18;
        
        if (age &lt; 0)
        {
            age = 18;
        }
        
        try
        {
            Person p = new Person(&quot;SwagiWagi&quot;, 18);
        }
        catch (AgeException ex)
        {
           System.out.println(&quot;This does not look right.&quot;);
        }
    }
}

In the first try block you want to catch a faulty input from the user or whatever gives the parameter for the Person object. And in the catch block you try to "correct" that input and check that with ANOTHER try-catch block for the SAME exception.

Whatever initially passed the faulty parameter should do it right in the first place. Handling exceptions should be used more like a way to detect problems during runtime, not to fix them.

If there is a way to simply correct the problem like asking the user to again input a correct value, you should of course do that, but that can be done without exceptions.
If it is not possible, like the argument is being given by some other program or thread you have no control over, there is no way to do that, so the program should crash.

huangapple
  • 本文由 发表于 2020年5月3日 16:27:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/61571587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定