Почему этот код Scala выдает ошибку IllegalAccessError во время выполнения?

У меня есть простое приложение:

object Test extends App {
  implicit def t2mapper[X, X0 <: X, X1 <: X](t: (X0, X1)) = new {
    def map[R](f: X => R) = (f(t._1), f(t._2))
  }
  println("Hello!")
  val (foo, bar) = (1, 2) map (_ * 2)
  println((foo, bar))
}

(t2mapperвзят из этого ответа .)

Код компилируется нормально:

$ scalac -version
Scala compiler version 2.9.1 -- Copyright 2002-2011, LAMP/EPFL
$ scalac -unchecked Test.scala
$ 

но при запуске выдаетIllegalAccessError(раньшеHello!печатается):

$ java -version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3)
OpenJDK Server VM (build 20.0-b12, mixed mode)
$ scala Test
java.lang.IllegalAccessError: tried to access field Test$.reflParams$Cache1 from class Test$delayedInit$body
        at Test$delayedInit$body.(Test.scala:6)
        at Test$.(Test.scala:1)
        at Test$.(Test.scala)
        at Test.main(Test.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
        at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
        at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Обратите внимание, что с заменой последних двух строк на

  println((1, 2) map (_ * 2))

или

  val (foo, bar) = (2, 4)
  println((foo, bar))

или

  val intermediate = (1, 2) map (_ * 2)
  val (foo, bar) = intermediate
  println((foo, bar))

он печатает (2,4), как и ожидалось. Но когда завернуты в блок

  {
    val intermediate = (1, 2) map (_ * 2)
    val (foo, bar) = intermediate
    println((foo, bar))
  }

или

  private val blah = {
    val intermediate = (1, 2) map (_ * 2)
    val (foo, bar) = intermediate
    println((foo, bar))
  }

он выдает исключение.

Почему первый и последний способы приводят к тому, что JVM выдает ошибку во время выполнения?

7
задан Community 23 May 2017 в 10:30
поделиться