timowest / scalagen

Java to Scala transformation
Apache License 2.0
217 stars 32 forks source link

Wrongly converts classes with multiple constructors #73

Open OlivierBlanvillain opened 10 years ago

OlivierBlanvillain commented 10 years ago

Here is an example:

class A {
    public A() {
        System.out.println(1);
    }
    public A(String s) {
        System.out.println(2);
    }
}

Which is converted to:

class A {
  println(1)
  def this(s: String) {
    this()
    println(2)
  }
}

Note that it might be impossible to perfectly match Java behavior, especially when inheritance is involved, see http://stackoverflow.com/questions/3299776/in-scala-how-can-i-subclass-a-java-class-with-multiple-constructors.

timowest commented 10 years ago

Sorry, this kind of delegation is the best that can be done.

OlivierBlanvillain commented 10 years ago

What about something like this? It does not look very nice but at least it's behavior equivalent:

class A private (n: Nothing) {
  def this() {
    this(null)
    println(1)
  }
  def this(s: String) {
    this(null)
    println(2)
  }
}
timowest commented 10 years ago

Hm, this is an interesting approach, I will consider it.

erikkaplun commented 10 years ago

@OlivierBlanvillain: why is the current behavior wrong? the default constructor shouldn't be declared explicitly in Scala... I would be very disappointed if Scala wrapped the default constructor in a def this().

timowest commented 10 years ago

I think the point is that if the behaviour can't be solved with constructor delegation then a common delegation target could be used.

This is again a tradeoff between correctness of the result vs having a scalaesque result.