Ale*_*ack 11 inheritance scala
说我有:
class A(val foo: String)
class B(foo: String) extends A(foo)
class C(val foo: String) extends A(foo)
class D(override val foo: String) extends A(foo)
class E(bar: String) extends A(bar)
Run Code Online (Sandbox Code Playgroud)
我对每个类的内存实例占用多少感兴趣.A类的实例将具有单个成员变量:foo.
B,C,D和E班怎么样?他们各有几个成员变量?我怀疑E会有两个(E.bar,A.foo),我希望D会有一个(A.foo),但我想知道B和C,他们可能有两个吗?(B.foo,A.foo)?
Rex*_*err 14
所有这一切都编译的例子(A,B,D,E)取准确的存储空间相同的量.事实上,甚至
class F(val bar: String) extends A(bar)
Run Code Online (Sandbox Code Playgroud)
将数据存储在一个字段中 - 它只是为同一个字段获取一个额外的存取方法.但是,如果你
class G(var bar: String) extends A(bar)
Run Code Online (Sandbox Code Playgroud)
然后构建一个新的领域.
您可以通过编译上面的示例并查看字节码来检查所有这些javap -c Classname(请注意2:构造函数中的putfield A):
public class Sizes$A extends java.lang.Object implements scala.ScalaObject{
public java.lang.String foo();
Code:
0: aload_0
1: getfield #11; //Field foo:Ljava/lang/String;
4: areturn
public Sizes$A(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #11; //Field foo:Ljava/lang/String;
5: aload_0
6: invokespecial #18; //Method java/lang/Object."<init>":()V
9: return
}
Run Code Online (Sandbox Code Playgroud)
(并且缺少额外的putfield F...)
public Sizes$F(java.lang.String);
Code:
0: aload_0
1: aload_1
2: invokespecial #15; //Method Sizes$A."<init>":(Ljava/lang/String;)V
5: return
Run Code Online (Sandbox Code Playgroud)
(再次出现一个G...)
public Sizes$G(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #11; //Field bar:Ljava/lang/String;
5: aload_0
6: aload_1
7: invokespecial #18; //Method Sizes$A."<init>":(Ljava/lang/String;)V
10: return
Run Code Online (Sandbox Code Playgroud)
您的类C将需要一个override关键字val foo来编译,使其与之相同D.它将存储自己的foo副本.你的类B不会添加存储,除非它的构造函数体之外的某个地方有一个引用foo.这将强制创建隐藏字段以保存构造函数参数.构造函数体是类定义中的所有代码,并且在任何方法体之外.
附录:
package storage
class A(val foo: String)
class B( foo: String) extends A(foo)
// class C( val foo: String) extends A(foo)
class D(override val foo: String) extends A(foo)
class E( bar: String) extends A(bar)
class F( bar: String) extends A(bar) { def barbar: String = bar }
Run Code Online (Sandbox Code Playgroud)
我为此感到困惑:
% javap -private storage.F
Compiled from "Storage.scala"
public class storage.F extends storage.A implements scala.ScalaObject{
public java.lang.String barbar();
public storage.F(java.lang.String);
}
Run Code Online (Sandbox Code Playgroud)
什么是barbar用于获取其返回值的方法?
| 归档时间: |
|
| 查看次数: |
7912 次 |
| 最近记录: |