2012-10-24 14 views
14

Ho un Scala classe:istanziare una classe Scala da Java, e utilizzare i parametri di default del costruttore

class Foo(val x:String = "default X", val y:String = "default Y") 

voglio chiamare da Java, ma utilizzando i parametri di default

Passaggio null non funziona (assegna null, come previsto)

new Foo(null,null); //both are instantiated as null 

Questo trucco ha funzionato per me, ma è brutto, e mi chiedo se ci sia un modo migliore:

Scala

class Foo(val x:String = "default X", val y:String = "default Y") { 
    def this(x:Object) = this() 
} 

Java

new Foo(null); //no matter what I pass it should work 

Tuttavia vorrei piace sbarazzarsi del trucco di sovraccarico del costruttore e utilizzare un costruttore 0 param

È possibile?

risposta

7

Sembra, non v'è alcun modo così: https://issues.scala-lang.org/browse/SI-4278

Problema: predefinito No-args costruttore dovrebbe essere generato per le classi con tutti-opzionali argomenti
...

Lukas Rytz: per quanto riguarda l'uniformità della lingua, abbiamo deciso di non risolvere questo problema - poiché si tratta di un problema di interoperabilità con i framework, pensiamo che non debba essere risolto a livello di linguaggio.

soluzioni: ripetere un default, o astratte su uno, o mettere uno di default int il costruttore zero argomento

Poi Lukas propone la stessa soluzione cui è stato trovato:

class C(a: A = aDefault, b: B = C.bDefault) { 
    def this() { this(b = C.bDefault) } 
} 
object C { def bDefault = ... } 

// OR 

class C(a: A = aDefault, b: B) { 
    def this() { this(b = bDefault) } 
} 
1

Più in generale se hai una classe Scala con argomenti di default e vuoi istanziare in Java sostituendo 0, 1 o più dei valori di default senza doverli specificare tutti, prendi in considerazione l'estensione dell'API di Scala per includere un Builder nell'oggetto companion.

case class Foo(
    a: String = "a", 
    b: String = "b", 
    c: String = "c") 

object Foo { 
    class Builder { 
    var a: String = "a" 
    var b: String = "b" 
    var c: String = "c" 
    def withA(x: String) = { a = x; this } 
    def withB(x: String) = { b = x; this } 
    def withC(x: String) = { c = x; this } 
    def build = Foo(a, b, c) 
    } 
} 
Problemi correlati