Home > Software engineering >  Can't throw exception in constructor of subclass
Can't throw exception in constructor of subclass

Time:07-07

I made 3 classes, a brand class (Marca), a comercial brand class (MarcaComercial) which is a subclass of the brand class and an exception class (ExMarcaInvalida) if one of the attributes initiated in the brand constructor is null. I wanna catch this exception in my subclass constructor and declare it and use a setter method if this exception is caught. However, I can't do it because I can't initiate the values of the superclass anywhere other then the first line. Is there a way to catch the exception and do what I want? Leaving all 3 class constructors below.

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");
    }
}
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");
    }
}

public class ExMarcaInvalida extends Exception{
    public ExMarcaInvalida(String msg){
        super(msg);
    }  
}

CodePudding user response:

Can't throw exception in constructor of subclass

The problem is NOT that you can't throw the exception.

The real problem is that you can't catch an exception thrown in a constructor's super call ... in the constructor itself. The super call must be the first statement of the constructor, and that means it cannot be inside a try ... catch.

If you really need to catch the exception, you need to use a factory method to create the object; e.g.

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.
    }
}

But even with a factory method, you can't "fix" and return the original object that you were creating. That object is not accessible to the factory method.

Basically, Java is preventing you from returning an instance where the superclass initialization has failed. It would be a broken abstraction, even it the fix made sense. The subclass would need to know about the private details of the superclass implementation. Anyhow ... Java doesn't allow it.


(Actually, I can think of a couple of horrible ways to subvert this ... but I won't describe them in case someone thinks they might be a good idea.)

  •  Tags:  
  • java
  • Related