0

I am trying to overload a constructor in java. There are two Strings among its variables which is problematic if I write two separate constructors in the case of only one of these strings being called. This is why I would like to use the following code :

public Timbre(String string){
    if(string.indexOf("-") == -1){
        this, ANNEE_COURANTE, string, VALEUR_TIMBRE_DEFAUT);
    } else{
        this(string, ANNEE_COURANTE, PAYS_DEFAUT, VALEUR_TIMBRE_DEFAUT);
    }
}

However, I am told by VSC that "Constructor call must be the first statement in a constructor". How can I overcome this problem?

  • The code does not compile, you are missing an opening bracket as well as a parameter in the first branch of the statement. `this, ANNEE_COURANTE, ...` won't be considered a constructor call. – deHaar Nov 21 '21 at 07:27
  • 1
    This appears to be a place where you will need a different creational strategy; using a `Builder` is probably appropriate. – Elliott Frisch Nov 21 '21 at 07:33

4 Answers4

3

You cannot use an if / else to choose between different this(...) or super(...) calls in constructor chaining. It is simply not allowed in Java. The this or super call must resolve to a single constructor overload at compile time.

(AFAIK) the only way that you can do "conditional things" in constructor chaining is like this:

public MyClass(...)
    this(boolean_expression ? yes_expression : no_expression, ...);
    ...
}

We are chaining to the same constructor overload in both cases, but with different argument values in the "yes" and "no" cases.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

For such purpose you should use Factory Design Pattern that in your case might be implemented even like this:

class Timbre{
    // various constructors - all private!

    // static factory method 
    public static Timbre of(String string){
        if(string.indexOf("-") == -1){
            return new Timbre(ANNEE_COURANTE, string, VALEUR_TIMBRE_DEFAUT);
        } else{
            return new Timbre(string, ANNEE_COURANTE, PAYS_DEFAUT, VALEUR_TIMBRE_DEFAUT);
        }
    }
}

Read more about factory design patterns:

m.antkowicz
  • 13,268
  • 18
  • 37
2

Java requires the call to this() to be first statement in a constructor. You can use a ternary expression to get the same effect as your if ... else .... However, you would need to call the same constructor for both paths.

You could try something like:

public Timbre(String string) {
  this(
    ANNEE_COURANTE,
    (string.indexOf("-") == -1) ? PAYS_DEFAUT : string,
    VALEUR_TIMBRE_DEFAUT
  );
}
dave
  • 11,641
  • 5
  • 47
  • 65
1

To overload constructors, you would require multiple constructor methods with different signatures.

As per your requirement, it looks like that you are passing a single parameter and want to decide the flow of execution based on its value.

To do so you can create two different methods which can be called accordingly based on conditions in a single constructor method like you are doing but change the call of this to a regular method.

Jasneet Dua
  • 3,796
  • 2
  • 10
  • 15