Java:编写异常

Java:编写异常,java,error-handling,Java,Error Handling,是否可以扩展已经存在的类以引发异常?例如,如果条目已经存在,是否可以为以下代码创建异常?(我无法修改类,因此我需要扩展,并且必须包含错误处理,而不仅仅是显示消息。) 入学类别: public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5) { this.firstName = paramString1;

是否可以扩展已经存在的类以引发异常?例如,如果条目已经存在,是否可以为以下代码创建异常?(我无法修改类,因此我需要扩展,并且必须包含错误处理,而不仅仅是显示消息。)

入学类别:

public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
  {
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
      this.postCode = paramString5;
    } else {
      System.err.printf("Bad postcode: '%s'\n", new Object[] { paramString5 });
      this.postCode = "???";
    }
  }
public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
{
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
        this.postCode = paramString5;
    } else {
        throw new MyException(String.format("Bad postcode: '%s'\n", new Object[] { paramString5 }));
    }
}
通讯录类别:

public String add(Entry paramEntry)
  {
    if (paramEntry == null)
      return "Error: null entry";
    if (this.data.contains(paramEntry)) {
      return "Error: this entry already in the book";
    }
    boolean bool = this.data.add(paramEntry);
    if (bool) {
      return " entry added";
    }
    return "entry could not be added";
  }
我搜索了互联网,发现了以下易于访问的网站:


这就是我需要做的吗?(java新手抱歉)

您可能会问自己的第一个问题,“我真的想为此抛出异常吗?”。异常应仅用于不应发生的事件,如
IOException
。我只需要使用
验证器
来验证用户输入。

您可能会问自己的第一个问题,“我真的想为此抛出异常吗?”。异常应仅用于不应发生的事件,如
IOException
。我只想使用
验证器
来验证用户输入。

在扩展类并重写所需方法后,您可以检查返回值或更新字段以决定是否引发异常,例如:

public String add(Entry paramEntry) //overridden 
  {

    String val = super.add(paramEntry); //call actual method

   if(val.equals("entry could not be added")) //check for exception condition
       throw new OperationException(val);//runtime exception

    return val;
  }

public class OperationException extends RuntimeException {

    public OperationException() {
        super();
    }

    public OperationException(String message, Throwable cause)  {
        super(message, cause);
    }
    public OperationException(String message){
        super(message);
    }

    public OperationException(Throwable cause)  {
        super(cause);
    }
}

扩展类并重写required方法后,可以检查返回值或更新的字段以决定是否引发异常,如:

public String add(Entry paramEntry) //overridden 
  {

    String val = super.add(paramEntry); //call actual method

   if(val.equals("entry could not be added")) //check for exception condition
       throw new OperationException(val);//runtime exception

    return val;
  }

public class OperationException extends RuntimeException {

    public OperationException() {
        super();
    }

    public OperationException(String message, Throwable cause)  {
        super(message, cause);
    }
    public OperationException(String message){
        super(message);
    }

    public OperationException(Throwable cause)  {
        super(cause);
    }
}

不可以,您不能重写类并将(选中的)异常添加到超类中不存在的签名。因此,您不能子类化
AddressBook
并重写
add()
来声明新的选中异常。在您的情况下,我甚至不建议重写
add
方法,因为它从根本上是错误的。我不推荐从
add
方法返回字符串(本质上是一个验证错误)。如果您真的想在这种情况下使用异常,可以重写该方法并抛出
RuntimeException
的实例。但是它只不过是猪上的口红。

不,你不能重写一个类,并且在超级类中不存在的签名中添加(检查)异常。因此,您不能子类化

AddressBook
并重写
add()
来声明新的选中异常。在您的情况下,我甚至不建议重写
add
方法,因为它从根本上是错误的。我不推荐从
add
方法返回字符串(本质上是一个验证错误)。如果您真的想在这种情况下使用异常,可以重写该方法并抛出
RuntimeException
的实例。但是,它确实是对猪的唇膏。

首先,扩展类与抛出异常无关。如果你想知道是否可以抛出一个异常,其中超级方法不抛出任何异常,那么答案是:

首先,扩展类与抛出异常无关。想知道的是,如果super方法不抛出任何异常,那么您是否可以抛出异常。答案是否。

您可以尝试使用RuntimeException的sume子类

在这种情况下,父类的方法签名将保持不变,但您可以在子类中抛出此异常

例如,异常代码:

public class MyException extends RuntimeException
{
    public MyException(String message)
    {
        super(message);
    }
}
然后是入门课程:

public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
  {
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
      this.postCode = paramString5;
    } else {
      System.err.printf("Bad postcode: '%s'\n", new Object[] { paramString5 });
      this.postCode = "???";
    }
  }
public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
{
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
        this.postCode = paramString5;
    } else {
        throw new MyException(String.format("Bad postcode: '%s'\n", new Object[] { paramString5 }));
    }
}
您需要在某个地方处理异常:

try
{
    /* create entry etc. */
}
catch(MyException e)
{
    /* ... */
}
因为您的示例中的条目和地址簿实际上都没有扩展任何内容,所以我假设您的条目是一个子类

地址簿也可以用类似的方式更改


请注意,这是无法更改父类的变通方法。如果可以更改父类,我将使用选中的异常。

您可以尝试使用RuntimeException的sume子类

在这种情况下,父类的方法签名将保持不变,但您可以在子类中抛出此异常

例如,异常代码:

public class MyException extends RuntimeException
{
    public MyException(String message)
    {
        super(message);
    }
}
然后是入门课程:

public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
  {
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
      this.postCode = paramString5;
    } else {
      System.err.printf("Bad postcode: '%s'\n", new Object[] { paramString5 });
      this.postCode = "???";
    }
  }
public Entry(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
{
    this.firstName = paramString1;
    this.lastName = paramString2;
    this.street = paramString3;
    this.town = paramString4;
    if (paramString5.matches("[A-Z]{2}[0-9]{1,2} [0-9]{1,2}[A-Z]{2}")) {
        this.postCode = paramString5;
    } else {
        throw new MyException(String.format("Bad postcode: '%s'\n", new Object[] { paramString5 }));
    }
}
您需要在某个地方处理异常:

try
{
    /* create entry etc. */
}
catch(MyException e)
{
    /* ... */
}
因为您的示例中的条目和地址簿实际上都没有扩展任何内容,所以我假设您的条目是一个子类

地址簿也可以用类似的方式更改


请注意,这是无法更改父类的变通方法。如果可以更改父类,我将使用选中的异常。

扩展类时,需要遵守Liskov替换原则

具体来说,这意味着在任何情况下,用户都可以使用Parent类型的对象,他也必须能够使用Child类型的对象

显然,您将看到添加(选中的)异常违反了这一点。如果客户机类正在使用父类,则它没有用于异常的throw子句或try/catch。因此,如果他与子类交换,代码将变得无效

所以,不,你不能

您可以添加RuntimeException,但这仍然是个坏主意


请参见

扩展类时,需要遵守Liskov替换原则

具体来说,这意味着在任何情况下,用户都可以使用Parent类型的对象,他也必须能够使用Child类型的对象

显然,您将看到添加(选中的)异常违反了这一点。如果客户机类正在使用父类,则它没有用于异常的throw子句或try/catch。因此,如果他与子类交换,代码将变得无效

所以,不,你不能

您可以添加RuntimeException,但这仍然是个坏主意


这是真的。例外情况仅适用于例外情况。应该通过正确验证来处理无效的用户输入。但有一个约束,即父类不能更改(及其方法的签名),因此没有地方添加来自验证程序的返回值(