3

I have a class with two constructors:

@JsType
public class Dog implements Animal {
    String name;

    public Dog() { 
        this.name = "Scooby Doo";
    }

    public Dog(String name) {
        this.name = name;
    }
}

I get the following error when I run gwt compile [With GWT-dev 2.8]

[ERROR] Constructor 'Dog(String)' can be a JsConstructor only if all constructors in the class are delegating to it.

I have been trying to work through this error, with not much success. I am not sure how to delegate to the other constructor.

Any help is very much appreciated!

Thanks!

Spiff
  • 3,873
  • 4
  • 25
  • 50
  • It's been a while that I've dealt with Java, but I'd guess that it wants all constructors to ultimately call a single implementation. Something like `public Dog(){ Dog("Scooby Doo") }` – Thomas Feb 05 '18 at 00:32

1 Answers1

2

Alas, JavaScript can't handle multiple constructors! You get one and only one.

There are some things you can do to pretend to have more than one - you can check the incoming data, and assign sane defaults:

@JsConstructor
public Dog(@JsOptional String name) {
    if (name == null) {
        name = "Scooby Doo";
    }
    this.name = name;
}

You have to be careful of types here if your two constructors do not use the same types in the same position - judicious use of instanceof might work (just be aware that for JS objects you are using JS instanceof, not java!). Another option lets you be more flexible, but again, no overloaded methods - factory methods:

public static Dog withName(String name) {
    return new Dog(name);
}
public static Doc defaultImpl() {
    return new Dog();
}

@JsIgnore
public Dog() {/*...*/}
@JsIgnore
public Dog(String name) {/*...*/}

Another idea on the same theme would be to create a JsType builder. This is a bit less idiomatic for JS.

Finally, you could consider the dreaded "options object", where your one constructor takes a single Object with properties, or a JsPropertyMap<Any> holding all the possible values, then check nullness and types inside the giant constructor. I avoid this personally - this is one of the terrible things I'm hoping to avoid by writing Java in the first place.

Colin Alworth
  • 17,801
  • 2
  • 26
  • 39