Scala 是否每次隐式类转换都会创建新的类实例?

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

我们在.class文件中看到

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 }