3

so my issue is that I have a class and its subclass.

-> class Kassenbon -> class KassenbonVerbessert extends Kassenbon

in my "Kassenbon" class I have this constructor:

   public Kassenbon(int max) {
        produkte = new String[max];
        preise = new Integer[max];
    }

and then the constructor of my subclass looks like this:

   public KassenbonVerbessert(int max) {
        super(max);
    }

My issue now is that I want to check the parameter max and if it is negative then I wanna throw an exception because that would mean that the constructor would create 2 arrays with a negative length which isnt possible. But how do I do it simply because the super call must be the first statement in the constructor right?! But how do I implement a:

if(max < 0){
   throw new IllegalArgumentException("Error");
}
EgZoShift
  • 29
  • 5

4 Answers4

4

First, it looks like that check would make more sense in the Kassenbon constructor. But if you don't want to do that, you can inline a method call to check the parameter:

public KassenbonVerbessert(int max) {
    super(checkMax(max));
}

private static int checkMax(int max) {
    if (max < 0) {
        throw new IllegalArgumentException("max cannot be negative.");
    }
    return max;
} 
khelwood
  • 55,782
  • 14
  • 81
  • 108
  • 1
    Thanks a lot this really helped me. Forgot to mention I cannot adjust the parent class so the solution with another method that I call within the super call is a nice solution tbh – EgZoShift Jan 02 '21 at 13:01
  • If this answer has solved your problem you have the option of [accepting the answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – khelwood Jan 02 '21 at 15:06
0

There's no compulsion that you need to put the check in the child class. You can directly put the check inside the constructor of your parent class.

0

When you are unable to apply the check to the parent constructor, you have to inline the check, as suggested here and here. But you don't have to write your own method for that, you can take java.util.Objects.checkIndex() for that purpose:

public KassenbonVerbessert( int max ) 
{
    super( java.util.Objects.checkIndex( max, Integer.MAX_VALUE ) );
}

The second argument is the maximum value for max, just if you want to provide an upper border as well …

And of course you can add a static import for that method: import static java.util.Objects.checkIndex;.

tquadrat
  • 3,033
  • 1
  • 16
  • 29
0

In addition to what @khelwood said, you could also force creation of a class using factory methods. Usually when creation of an object gets even more complex - especially in regards to checks and Exceptions - you start using those:

package stackoverflow.kassensystem;

public class Kassenbon {

    private final String[]  produkte;
    private final Integer[] preise;

    public Kassenbon(final int max) {
        produkte = new String[max];
        preise = new Integer[max];
    }

}

and

package stackoverflow.kassensystem;

public class KassenbonVerbessert extends Kassenbon {

    static public KassenbonVerbessert createInstance(final int max) {
        if (max < 0) throw new IllegalArgumentException("Parameter 'max' is out of valid bounds! Expected max>0, but got '" + max + "' instead.");
        return new KassenbonVerbessert(max);
    }

    private KassenbonVerbessert(final int max) {
        super(max);
    }

}

How to use:

package stackoverflow.kassensystem;

public class KassenSystem {

    public static void main(final String[] args) {
        System.out.println("KassenSystem.main() startet...");
        // KassenbonVerbessert kb1 = new KassenbonVerbessert(20); this line cannot work, because KassenbonVerbessert CTOR is private. Must instanciate via static method
        final KassenbonVerbessert kb2 = KassenbonVerbessert.createInstance(20); // this works alright
        final KassenbonVerbessert kb3 = KassenbonVerbessert.createInstance(-666); // this will fail
    }

}
JayC667
  • 2,418
  • 2
  • 17
  • 31
  • Oh, and the more detailed your Exceptions are, the better. You will thank yourself later. Just make sure you do not include passwords and other secrets into exceptions, because in Java you're not completely in control over how Exception Handling is done; it can easily be influenced from the outside. – JayC667 Jan 02 '21 at 15:05