Что такое Scala-эквивалент статического блока Java? (без объекта-компаньона)

Есть ли в 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: я уже прочитал Что такое Scala-эквивалент статического блока Java? этот ответ, но я не хочу создавать сопутствующий объект, а затем вызывать его через конструктор класса.

Изменить: [Мой вариант использования]

Рассмотрим сценарий java, где мы пишем Class.forName("some.jdbc.driver") внутри статического блока, а затем помещаем драйвер jdbc в путь к классу. После этого загрузчик классов загружает упомянутый нами класс. Я хочу сделать что-то точно такое


person nomadSK25    schedule 17.07.2018    source источник
comment
Нет, ответ, на который вы ссылаетесь, является ближайшим эквивалентом Scala.   -  person Alexey Romanov    schedule 17.07.2018
comment
По какой причине его нет в компаньоне?   -  person cchantep    schedule 17.07.2018
comment
@cchantep Потому что тогда вам нужно сделать что-то вроде этого object Test { class A { A }; object A { println("A.init") }} Я не хочу этого делать. Пожалуйста, посмотрите на вышеуказанную проблему с точки зрения загрузчика классов.   -  person nomadSK25    schedule 18.07.2018
comment
Это привычка, а не техническое требование, поскольку объект отвечает на вопрос   -  person cchantep    schedule 18.07.2018
comment
Объект @cchantep не отвечает на этот вопрос. Я хочу поместить что-то внутри статического блока, который может быть выполнен во время загрузки класса загрузчиком классов.   -  person nomadSK25    schedule 19.07.2018
comment
Так и есть, поскольку это идиоматический способ сделать это в Scala.   -  person cchantep    schedule 19.07.2018


Ответы (2)


Редактировать: никто не возлагал особых надежд, поэтому вот ссылка на SIP для @static участники. Он уже реализован для Dotty/Scala 3.

Однако члены определяются на компаньоне. Правая часть определений элементов может содержать произвольный код, поэтому синтаксис для статических инициализаторов как таковой не нужен.

Все еще интересно, каков вариант использования.

Каков ваш вариант использования?

Обычно:

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$
person som-snytt    schedule 17.07.2018
comment
Рассмотрим сценарий java, где мы помещаем Class.forName(some.jdbc.driver) внутри статического блока, а драйвер jdbc находится в пути к классу. После того, как загрузчик классов загружает упомянутый нами класс. Я хочу сделать что-то именно такое. Так что ваш ответ неактуален. Кстати, спасибо за указание на SIP. - person nomadSK25; 18.07.2018
comment
Я забыл упомянуть, что я делаю spark-submit. - person nomadSK25; 19.07.2018

Я думаю, что ответ, на который вы ссылаетесь, - единственный ответ, который вы получите.

Если у вас есть код, подобный приведенному ниже, вам все равно нужно каким-то образом сослаться на объект, чтобы запустить код инициализации.

object StaticBlock {
  println("init")
}

То же самое и в Java: пока вы не загрузите класс, статические блоки в этом классе не выполняются.

person daniel kullmann    schedule 17.07.2018