子类的构造函数中不能抛出异常

jor*_*ndo 2 java

我创建了 3 个类:品牌类 (Marca)、商业品牌类 (MarcaComercial)(品牌类的子类)和异常类 (ExMarcaInvalida)(如果品牌构造函数中启动的属性之一为 null)。我想在子类构造函数中捕获此异常并声明它,如果捕获此异常则使用 setter 方法。但是,我不能这样做,因为除了第一行之外,我无法在任何地方启动超类的值。有没有办法捕获异常并做我想做的事情?保留下面所有 3 个类构造函数。

public Marca(String nome, String produtor, String regiao) 
        throws ExMarcaInvalida {
    this.nome = nome;
    this.produtor = produtor;
    this.regiao = regiao;
    if(nome.isEmpty() || nome.isBlank()){
        throw new ExMarcaInvalida("Nome invalido");
    }
}
Run Code Online (Sandbox Code Playgroud)
public MarcaComercial(String rotulo, String email, 
    String num, String nome,String produtor, String regiao) 
    throws ExMarcaInvalida {
    try{
        super(nome, produtor, regiao); //ISSUE HERE
        this.rotulo = rotulo;
        this.email = email;
        this.num = num;
    }
    catch(ExMarcaInvalida e){
        setRotulo("Marca Branca");
        throw new ExMarcaInvalida("Marca Invalida");
    }
}

Run Code Online (Sandbox Code Playgroud)
public class ExMarcaInvalida extends Exception{
    public ExMarcaInvalida(String msg){
        super(msg);
    }  
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 6

子类的构造函数中不能抛出异常

问题不在于你不能抛出异常。

真正的问题是,您无法在构造函数本身中捕获构造函数调用中引发的异常super。该super调用必须是构造函数的第一条语句,这意味着它不能位于try ... catch.

如果确实需要捕获异常,则需要使用工厂方法来创建对象;例如

public MarcaComercial makeMarcaComercial(...) {
    try {
        return new MarcaComercial(...);
    } catch (ExMarcaInvalida ex) {
        // This will catch the exception whether it is thrown by 
        // the Marca constrictor or the MarcaComercial constructor
        //
        // Now we can throw a new exception or return a different object.
    }
}
Run Code Online (Sandbox Code Playgroud)

但即使使用工厂方法,您也无法“修复”并返回您正在创建的原始对象。工厂方法无法访问该对象。

基本上,Java 会阻止您返回超类初始化失败的实例。这将是一个破碎的抽象,即使修复是有意义的。子类需要了解超类实现的私有细节。无论如何...Java不允许这样做。


(实际上,我可以想到一些可怕的方法来颠覆这一点......但我不会描述它们,以防有人认为它们可能是个好主意。)