case class, object的底层实现
来源:互联网 发布:关键词排列组合软件 编辑:程序博客网 时间:2024/05/01 23:35
object和class的关系
class O{ def func() { O.func();println("No!") }}object O{ def func() {println("O!") }}都定义了func()方法,但是实际上不冲突;
上述代码转化为java的结果:
public final class O${ public static final MODULE$; static { new (); } public void func() { Predef..MODULE$.println("O!"); } private O$() { MODULE$ = this; }}public class O{ public void func() { O..MODULE$.func(); Predef..MODULE$.println("No!"); }}
可看出:
1 实际上会产生2个类, 分别是O和O$;
2 O$是单例类, MODULE$是单例对象;3 对伴生对象O的调用,都会转化为对O$.MODULE$的调用;
class A{ var a = 2; //和object A有同名的变量,这种情况下,不会为java的A类生成static int a的静态变量;}object A{ def func() { println("O A") } var a = 1; }
Java的代码如下:
public class A{ private int a = 2; public static void func() { A..MODULE$.func(); } public int a() { return this.a; } public void a_$eq(int x$1) { this.a = x$1; }}public final class A${ public static final MODULE$; private int a; static { new (); } public void func() { Predef..MODULE$.println("O A"); } public int a() { return this.a; } public void a_$eq(int x$1) { this.a = x$1; } private A$() { MODULE$ = this; this.a = 1; }}1 scala类的任何成员变量,在java都是private的,且都会生成相应的存取方法, 且set方法命名: xxx_$eq.
2 A类没有定义func()方法,所以为A类生成了func()方法,里面直接调用A$类的同名方法,这样A类的对象等于就有了func()方法.
3 scala中,对A.a的调用,都会转化为对A$的方法的调用;
4 如果object A中声明了a, class A没有声明a,则会在java层为A生成static int a的变量和存取方法,但是不会被调用到;
5 如果object A中声明了a, class A也声明了a,则就不会在java层为A生成static int a;
6 若只定义了object A, 没有定义class A, 则java层也会生成class A,但是不可用;
上面4,5其实都无所谓,因为第3条才是根本, 即对A.a的调用, 都会直接route到对A$的方法的调用;
class B{ var x = 10;}case object B{ def func() { println("O B") } var b = 1;}转化为的java代码:
public class B{ private int x = 10; public static boolean canEqual(Object paramObject) { return B..MODULE$.canEqual(paramObject); } public static Iterator<Object> productIterator() { return B..MODULE$.productIterator(); } public static Object productElement(int paramInt) { return B..MODULE$.productElement(paramInt); } public static int productArity() { return B..MODULE$.productArity(); } public static String productPrefix() { return B..MODULE$.productPrefix(); } public static void b_$eq(int paramInt) { B..MODULE$.b_$eq(paramInt); } public static int b() { return B..MODULE$.b(); } public static void func() { B..MODULE$.func(); } public int x() { return this.x; } public void x_$eq(int x$1) { this.x = x$1; }}public final class B$ implements Product, Serializable{ public static final MODULE$; private int b; static { new (); } public void func() { Predef..MODULE$.println("O B"); } public int b() { return this.b; } public void b_$eq(int x$1) { this.b = x$1; } public String productPrefix() { return "B"; } public int productArity() { return 0; } public Object productElement(int x$1) { int i = x$1; throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(x$1).toString()); } public Iterator<Object> productIterator() { return ScalaRunTime..MODULE$.typedProductIterator(this); } public boolean canEqual(Object x$1) { return x$1 instanceof ; } public int hashCode() { return 66; } public String toString() { return "B"; } private Object readResolve() { return MODULE$; } private B$() { MODULE$ = this; Product.class.$init$(this); this.b = 1; }}
case class和class的关系
case class C(c1: Int){ var c = c1;}转化为的java代码:
public class C implements Product, Serializable{ private final int c1; private int c; public static Option<Object> unapply(C paramC) { return C..MODULE$.unapply(paramC); } public static C apply(int paramInt) { return C..MODULE$.apply(paramInt); } public static <A> Function1<Object, A> andThen(Function1<C, A> paramFunction1) { return C..MODULE$.andThen(paramFunction1); } public static <A> Function1<A, C> compose(Function1<A, Object> paramFunction1) { return C..MODULE$.compose(paramFunction1); } public int c1() { return this.c1; } public int c() { return this.c; } public int copy$default$1() { return c1(); } public void c_$eq(int x$1) { this.c = x$1; } public C copy(int c1) { return new C(c1); } public String productPrefix() { return "C"; } public int productArity() { return 1; } public Object productElement(int x$1) { int i = x$1; switch (i) { default: throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(x$1).toString()); case 0: } return BoxesRunTime.boxToInteger(c1()); } public Iterator<Object> productIterator() { return ScalaRunTime..MODULE$.typedProductIterator(this); } public boolean canEqual(Object x$1) { return x$1 instanceof C; } public int hashCode() { int i = -889275714; i = Statics.mix(i, c1()); return Statics.finalizeHash(i, 1); } public String toString() { return ScalaRunTime..MODULE$._toString(this); } public boolean equals(Object x$1) { C localC; if (this != x$1) { Object localObject = x$1; int i; if ((localObject instanceof C)) i = 1; else i = 0; if (i == 0) break label64; localC = (C)x$1; } label64: return ((c1() == localC.c1()) && (localC.canEqual(this)) ? 1 : 0) != 0; } public C(int c1) { Product.class.$init$(this); this.c = c1; }}
最后总结
class D ---------> 只会生成class D类object A ---------> 生成A和A$, 但是A无意义,都是A$的转发,且不能被调用(因为scala层认为没有定义class A,编译不通过);
case class C ------> 生成C和C$; 定义了C$的apply()方法;
case object B -----> 生成B和B$; 同样,B是B$的转发,且不可用; B$实现了Serializable接口;
scala的()运算,会转化为调用伴生对象的apply()方法, case class C会为C$生成apply()方法,里面调用了C的构造方法;
之所以说是调用了C$的apply()而不是C的apply(),原因前面也说过, scala层对C这个标识符(即类名)的使用都会转化为java层的C$;
0 0
- case class, object的底层实现
- case class与case object实战
- scala之case class 和case object
- scala-29:Case class和Case object代码实战解析
- 29.Case class 和Case object代码实战解析
- scala的case class
- 关于Object-C 底层实现self isa 的理解
- Java中Object类hashCode的底层实现
- 关于Object-C 底层实现self isa 的理解
- scala学习笔记3-Actor、case class和object、loop和react的使用
- Scala模式匹配,case 字符串,case 匹配类型,case 匹配数组,case 匹配List,case 匹配元组,case匹配case class和case object
- Scala class和case class的区别
- Scala class和case class的区别
- Scala class与Case class的区别
- case class 和 class的区别
- Scala class和case class的区别
- Scala class和case class的区别
- Class、Object的关系
- 线程大小设置
- 伊面
- Android开发-自定义View-AndroidStudio(十三)仿ViewPager(3)
- openstack neutron基本原理
- Android Studio --- android gradle plugin version 2.3.0-alpha1 is too old 解决办法
- case class, object的底层实现
- 4.1 docker-1.12 run命令运行以及参数详解
- web前端之MVC的JavaScript Web富应用开发一:MVC和类
- 11.C++ 内联成员函数、对象、
- 《从零开始学Swift》学习笔记(Day 55)——使用try?和try!区别
- 简述uwsgi使用一个服务启动多个文件的用法
- svn常用的几个命令
- LeetCode167---Input array is sorted
- css截取td里面的内容 如何固定td th的宽度