我不知道在哪裏的算法自動合併和明確的同伴對象描述或記錄(比編譯器源等),但通過編譯代碼,然後檢查所生成的同伴對象(使用javap的) ,我們可以看到有什麼不同(這與scala 2.10.4有關)。
下面是case類生成的同伴對象(沒有你額外的同伴對象):
Compiled from "zip.sc"
public final class A$ extends scala.runtime.AbstractFunction2<Object, Object, A> implements scala.Serializable {
public static final A$ MODULE$;
public static {};
public A apply(int, int);
public scala.Option<scala.Tuple2<java.lang.Object, java.lang.Object>> unapply(A);
public java.lang.Object apply(java.lang.Object, java.lang.Object);
public final java.lang.String toString();
}
加入你的同伴對象後,這裏會產生什麼:
Compiled from "zip.sc"
public final class A$ implements scala.Serializable {
public static final A$ MODULE$;
public static {};
public A apply(int, int);
public scala.Option<scala.Tuple2<java.lang.Object, java.lang.Object>> unapply(A);
public int A2Int(A);
}
的差異生成的伴侶對象由顯式伴侶對象定義引起的似乎爲:
- 它不再延長AbstractFunction2
- 它不再有工廠方法(適用)有關子彈1
- 它不再覆蓋toString方法(我假設你預計供應一個,如果需要的話)
- 您A2Int方法添加
如果案件類改爲普通類(連同得到它來編譯所需最小的變化),其結果如下:
Compiled from "zip.sc"
public final class A$ {
public static final A$ MODULE$;
public static {};
public A apply(int, int);
public int A2Int(A);
}
所以,如果你聲明你自己的伴侶對象,至少在這個簡單的例子中,效果是你的新方法被添加到伴隨對象中,並且它的一些實現和功能也會丟失。如果我們試圖覆蓋一些剩餘的自動生成的東西,但是剩下的不多,會發生什麼情況會很有趣,所以一般情況下不太可能導致衝突。
case類的一些優點與生成的代碼無關,例如公開類變量而不必顯式添加'val'關鍵字。以下是上述所有3個反編譯示例的修改源代碼。
版本1(沒有明確的同伴對象):
case class A(i1:Int,i2:Int)
2版是您的原始版本。
版本3(任何情況下級):
object A {
implicit def A2Int(a:A)=a.i1
def apply(a:Int,b:Int):A = new A(a,b)
}
class A(val i1:Int,val i2:Int)
object Run extends App{
import A._
val a=A(1,2)
val i:Int=a
}
在3版本,我們需要VAL添加到A級參數(否則它們是私有的),我們必須以添加工廠方法到我們的伴侶對象,或者在創建A(1,2)的實例時使用'new'關鍵字。