2011-10-28 10 views
6

Sembra Scala compila metodi compagno di oggetti in metodi statici, che li rende invocando dal codice Java un po 'più facile. Ad esempio, è possibile scrivere CompanionObject.method() anziché CompanionObject $ .MODULE $ .method(). Tuttavia, a volte il cambio di codice apparentemente irrilevante interromperà questo comportamento. Sono venuto con questo esempio per illustrare il problemaMetodo nell'oggetto companion compilato in metodi statici in scala?

$ cat TestCompanion.scala 
class TestCompanion 

object TestCompanion { 
    def init2 {} 
} 

@SerialVersionUID(1L) 
class TestCompanion2 

object TestCompanion2 { 
    def init2 {} 
} 


$ scalac -version 
Scala compiler version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL 

$ scalac TestCompanion.scala 
$ javap TestCompanion 
Compiled from "TestCompanion.scala" 
public class TestCompanion extends java.lang.Object implements scala.ScalaObject{ 
    public static final void init2(); 
    public TestCompanion(); 
} 

$ javap TestCompanion2 
Compiled from "TestCompanion.scala" 
public class TestCompanion2 extends java.lang.Object implements scala.ScalaObject{ 
    public static final long serialVersionUID; 
    public static {}; 
    public TestCompanion2(); 
} 

Quindi l'unica differenza tra TestCompanion e TestCompanion2 è che quest'ultimo è annotata con @SerialVersionUID e init2 viene compilato in un metodo statico in TestCompanion ma non in TestCompanion2.

qualcuno può spiegare perché scalac considera queste due classi in modo diverso? Non vedo come l'annotazione @SerialVersionUID dovrebbe influire sulla disponibilità di metodi statici.

+0

Stesso comportamento 2.9.1 & 2.10.0.r25798-b20111007020214. Sembra un bug per me, o almeno un'incoerenza –

+0

Questo bug è stato corretto in 2.10.0-M3 e versioni successive. – soc

risposta

4

Si tratta di un bug noto: Static forwarders are missing after adding @SerialVersionUID, sollevata da Josh Tosse. Dalla descrizione del problema:

Nel seguente codice, aggiungendo @SerialVersionUID alla classe risultati nelle spedizionieri statiche mancanti dal codice byte.

object WithoutUID { 
val instance = new WithoutUID 
} 
class WithoutUID extends scala.Serializable 

object WithUID { 
val instance = new WithUID 
} 
@SerialVersionUID(0) 
class WithUID extends scala.Serializable 

Ecco il codice di byte decompilato rilevanti:

public class WithoutUID implements Serializable, ScalaObject { 
    public static final WithoutUID instance(){ 
    return WithoutUID.MODULE$.instance(); 
    } 
} 

public class WithUID implements Serializable, ScalaObject { 
    public static final long serialVersionUID = 0L; 
}