2012-07-02 65 views
5

我有一个简单的应用程序:(该t2mapperthis answer为什么这个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)) 
} 

代码编译罚款:

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

,但在运行时,它抛出一个IllegalAccessErrorHello!获得印刷):

 
$ 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在运行时抛出错误?

+0

我在https://issues.scala-lang.org/browse/SI-6019报告了这个问题。 –

回答

4

它看起来像有一些相关的未解决的bug。例如,这一个可能涉及:

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

注意,你还可以创建一个main方法,而不是延长App,它会工作。

编辑:

当你使用这条线(我扩大了隐含的):在Eclipse

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

然后将鼠标悬停foobar,它显示private[this] val foo

因此,它看起来与SI-5251非常相似。

+0

我不认为这是错误,因为在我的第一个例子中,一切都是公开的。 –

+0

无论如何,你认为这只是一个编译器错误? –

+0

@Mechanicalsnail - 我认为这可能是我提到的bug 5251的一个变种。查看我的编辑的原因。 – david

相关问题