【问题标题】:What is Scala equivalent of Java's static block? (without companion object)Scala 等价于 Java 的静态块是什么? (没有伴随对象)
【发布时间】:2018-07-17 06:38:51
【问题描述】:

scala 是否有类似于类加载器对 java 中的静态块所做的类似操作?

例如在 scala 中类似于以下内容:

class A{
static{

System.out.println("This gets called at the time of loading a class by class loader.")
}
}

我将 Scala 2.x 与 Apache Spark 2.x 一起使用

PS:我已经阅读了What is Scala equivalent of Java's static block?这个答案,但我不想创建伴生对象然后通过类的构造函数调用它。

编辑:[我的用例]

考虑一个 java 场景,我们在静态块中编写 Class.forName("some.jdbc.driver") ,然后将 jdbc 驱动程序放在类路径中。在该类加载器加载我们提到的类之后。我想做一些完全一样的事情

【问题讨论】:

  • 不,您链接的答案是最接近的等效 Scala。
  • 同伴中没有它的原因是什么?
  • @cchantep 因为那你需要做这样的事情object Test { class A { A }; object A { println("A.init") }}我不想那样做。请从类加载器的角度来看上述问题。
  • 这是一种习惯,而不是技术要求,因为对象回答了问题
  • @cchantep 对象不回答这个问题。我想在静态块中放一些东西,可以在类加载器加载类时执行

标签: java scala apache-spark classloader static-block


【解决方案1】:

编辑:没有人提供太多希望,所以这里有一个指向the SIP for @static members 的链接。已经是implemented for Dotty/Scala 3了。

但是,成员是在同伴上定义的。成员定义的 RHS 可以包含任意代码,因此不需要静态初始化器的语法。

仍然想知道用例是什么。

你的用例是什么?

通常:

scala 2.13.0-M4> object X { println("hi") }
defined object X

scala 2.13.0-M4> X
hi
res0: X.type = X$@554c4eaa

scala 2.13.0-M4> :javap -c X
Compiled from "<console>"
public class $line3.$read$$iw$$iw$X$ {
  public static $line3.$read$$iw$$iw$X$ MODULE$;

  public static {};
    Code:
       0: new           #2                  // class $line3/$read$$iw$$iw$X$
       3: invokespecial #20                 // Method "<init>":()V
       6: return

  public $line3.$read$$iw$$iw$X$();
    Code:
       0: aload_0
       1: invokespecial #21                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: putstatic     #23                 // Field MODULE$:L$line3/$read$$iw$$iw$X$;
       8: getstatic     #28                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
      11: ldc           #30                 // String hi
      13: invokevirtual #34                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
      16: return
}

为了让你相信这是普通的静态加载:

scala 2.13.0-M4> :pa -raw
// Entering paste mode (ctrl-D to finish)

package y { object Y { println("hi") } }

// Exiting paste mode, now interpreting.


scala 2.13.0-M4> Class.forName
   def forName(x$1: String,x$2: Boolean,x$3: ClassLoader): Class[_]   def forName(x$1: String): Class[_]

scala 2.13.0-M4> Class.forName("y.Y$", true, getClass.getClassLoader)
hi
res5: Class[_] = class y.Y$

【讨论】:

  • 考虑一个 java 场景,我们将 Class.forName("some.jdbc.driver") 放在静态块中,而 jdbc 驱动程序位于类路径中。在该类加载器加载我们提到的类之后。我想做一些完全一样的事情。所以你的答案是无关紧要的。 BTW thnx 指出 SIP。
  • 我忘了说我正在做 spark-submit。
【解决方案2】:

我认为你所引用的答案是你会得到的唯一答案。

如果您有如下代码,您仍然需要引用该对象 以某种方式让初始化代码运行。

object StaticBlock {
  println("init")
}

这在 Java 中也是一样的:除非 加载类,该类中的静态块不会被执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多