[英]Why does this Scala code throw 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))
}
(The t2mapper
is from this answer .) (
t2mapper
来自这个答案 。)
The code compiles fine: 代码编译正常:
$ scalac -version
Scala compiler version 2.9.1 -- Copyright 2002-2011, LAMP/EPFL
$ scalac -unchecked Test.scala
$
but when run, it throws an IllegalAccessError
( before Hello!
gets printed): 但是在运行时,它会抛出
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)
Note that with the last two lines 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 (2,4)
as expected. 它按预期打印
(2,4)
。 But when wrapped in a block 但当包裹在一个街区
{
val intermediate = (1, 2) map (_ * 2)
val (foo, bar) = intermediate
println((foo, bar))
}
or 要么
private val blah = {
val intermediate = (1, 2) map (_ * 2)
val (foo, bar) = intermediate
println((foo, bar))
}
it throws the exception. 它引发了异常。
Why do the first and last ways cause an the JVM to throw an error at runtime? 为什么第一种和最后一种方式会导致JVM在运行时抛出错误?
It looks like there are a few relevant open bugs. 看起来有一些相关的开放漏洞。 For example, this one might be related:
例如,这个可能是相关的:
https://issues.scala-lang.org/browse/SI-5251?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel https://issues.scala-lang.org/browse/SI-5251?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
Note you can also create a main
method instead of extending App
and it will work. 请注意,您也可以创建一个
main
方法而不是扩展App
,它将起作用。
EDIT: 编辑:
When you use this line (I expanded the implicit): 当你使用这一行时(我扩展了隐含的):
val (foo, bar) = t2mapper((1, 2)) map (_ * 2)
And then mouseover foo
or bar
in Eclipse, it shows private[this] val foo
. 然后在Eclipse中鼠标悬停
foo
或bar
,它显示private[this] val foo
。
Therefore, it seems very similar to SI-5251. 因此,它似乎与SI-5251非常相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.