Java – why does this Scala code throw an illegalaccesserror at runtime?

I have a simple application:

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 starts with this answer.)

Code compilation is normal:

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

However, at run time, it will throw illegalaccesserror (before Hello! Is printed):

$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)

Notice that the last two lines are replaced with

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

or

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

or

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

It prints as expected (2,4) But when the package is one block away

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

or

private val blah = {
    val intermediate = (1,bar))
  }

It threw an exception

Why do the first and last methods cause the JVM to throw errors at runtime?

Solution

It seems that there are some related open loopholes For example, this may be relevant:

https://issues.scala-lang.org/browse/SI-5251?page=com.atlassian.jira.plugin.system.issuetabpanels:all -tabpanel

Note that you can also create a main method instead of extending the app, which will work

Edit:

When you use this line (I extend the implicit):

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

Then hover over foo or bar in eclipse, which displays private [this] Val foo

Therefore, it seems to be very similar to si-5251

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>