Scala 是否每次隐式类转换都会创建新的类实例?
我们在.class文件中看到Scala 是否每次隐式类转换都会创建新的类实例?,scala,implicit,Scala,Implicit,我们在.class文件中看到 object test extends App { implicit class f(i: Int) { println("!!!"); def f = 42 + i } 1.f 2.f 3.f } 所以,看起来有一个静态方法,但这段代码在运行时会打印3次“!!!”。每个隐式类转换都有新的类实例化吗?若有,原因为何?如果否,为什么要三次打印“!!!”呢?是-隐式类是创建类的缩写,隐式定义是创建实例的缩写,即在您的示例中: public static
object test extends App {
implicit class f(i: Int) { println("!!!"); def f = 42 + i }
1.f
2.f
3.f
}
所以,看起来有一个静态方法,但这段代码在运行时会打印3次“!!!”。每个隐式类转换都有新的类实例化吗?若有,原因为何?如果否,为什么要三次打印“!!!”呢?是-隐式类是创建类的缩写,隐式定义是创建实例的缩写,即在您的示例中:
public static test$f f(int);
Code:
0: getstatic #16 // Field test$.MODULE$:Ltest$;
3: iload_0
4: invokevirtual #42 // Method test$.f:(I)Ltest$f;
7: areturn
通过将扩展类设置为 请注意,这样您就不能将
println
放在里面,但这里有一个引用自上面链接的文档:
在运行时,此表达式3.toHexString被优化为等效于对静态对象(RichInt$.MODULE$.extension$toHexString(3))的方法调用,而不是对新实例化的对象的方法调用
我知道AnyVal,我的问题是关于“发生了什么”和“为什么会发生”?我的意思是,为什么要创建一个静态方法而不使用它,你不需要每次都创建新类,因为它是静态的?好吧,我无法解释。但我最好的猜测是,这完全是因为它是一个具有非静态初始化块的类。我认为,如果您使用该方法
f
隐式转换为对象
,它将是一个真正的静态方法。因此,它被编译为静态方法。为什么scala每次仍然创建新类,静态方法不需要这样做?或者,例如,scala可以缓存f
实例。创建了f
的一个实例,因为主体是这么说的:newf(i)
。2.无法缓存实例,因为不同的实例具有不同的构造函数参数。我看不到在此创建任何新类。你能澄清一下吗?@JörgWMittag每次运行1.f
时,你都会创建并分配类f
的新实例。理论上是这样的,但JVM足够聪明,如果不需要的话,就不会真正创建它们。所以它不会比使用静态方法慢。我手头没有证据,但如果你愿意,你可以试试。@dveim:当然,但这并不是在创建一个新类,所以我仍然看不到任何新类是如何创建的。@JörgWMittag重命名了这个问题以澄清问题。
object test extends App {
class f(i: Int) { println("!!!"); def f=42+i}
implicit def toF(i : int) = new f(i)
}
implicit class f(val i: Int) extends AnyVal { def f = 42 + i }