java - 引用内部静态 Java 类时工具箱编译的奇怪行为

标签 java scala reflection scala-2.10 toolbox

假设我有以下 java 类:

package com.test;
public class Outer {
    public static class Inner { public static final String VAL = "Inner"; }
}

我可以像您期望的那样从 Scala 代码中引用 VAL 常量,但是当我尝试使用 Scala 工具箱编译器编译引用该字段的代码时,它失败了。 (堆栈跟踪遵循以下示例)。

这段代码演示了我的意思:

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
object Issue extends App {
  val mirror = universe.runtimeMirror(getClass.getClassLoader)
  val toolbox = ToolBox(mirror).mkToolBox()
  println                  (com.test.Outer.Inner.VAL) // prints 'Inner'
  val tree = toolbox.parse("com.test.Outer.Inner.VAL")
  val compiled = toolbox.compile(tree)() // fails to compile
}

这是我得到的异常跟踪:

Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has failed: 

value Inner is not a member of object com.test.Outer
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:319)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:252)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416)
    at Issue$delayedInit$body.apply(Issue.scala:8)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    at scala.App$class.main(App.scala:71)
    at Issue$.main(Issue.scala:3)
    at Issue.main(Issue.scala)

有没有人遇到过这个?有什么我可以更改的(即编译器选项)来完成这项工作吗?

谢谢。

编辑

这是我用“-verbose -Yissue-debug”编译时得到的结果:

[reflect-compiler] made Scala package scala
[reflect-compiler] unpickling Scala package package and package scala, owner = package scala
[reflect-compiler] made Scala package java
[reflect-compiler] made Scala package lang
[reflect-compiler] made Scala package runtime
[reflect-compiler] made Scala package annotation
[reflect-compiler] unpickling Scala package package and package runtime, owner = package runtime
[reflect-compiler] made Scala package collection
[reflect-compiler] unpickling Scala package package and package collection, owner = package collection
[reflect-compiler] translating reflection info for Java class java.lang.Object
[reflect-compiler] unpickling Scala class Unit and object Unit, owner = package scala
[reflect-compiler] translating reflection info for Java class java.lang.Throwable
[reflect-compiler] unpickling Scala class Long and object Long, owner = package scala
[reflect-compiler] translating reflection info for Java class java.lang.InterruptedException
[reflect-compiler] unpickling Scala class Int and object Int, owner = package scala
[reflect-compiler] unpickling Scala class Boolean and object Boolean, owner = package scala
[reflect-compiler] translating reflection info for Java class java.lang.String
[reflect-compiler] translating reflection info for Java class java.lang.CloneNotSupportedException
[reflect-compiler] made Scala package io
[reflect-compiler] translating reflection info for Java interface java.io.Serializable
[reflect-compiler] translating reflection info for Java interface java.lang.CharSequence
[reflect-compiler] unpickling Scala class Char and object Char, owner = package scala
[reflect-compiler] translating reflection info for Java class java.io.ObjectStreamField
[reflect-compiler] made Scala package util
[reflect-compiler] unpickling Scala class Float and object Float, owner = package scala
[reflect-compiler] unpickling Scala class Double and object Double, owner = package scala
[reflect-compiler] unpickling Scala class Byte and object Byte, owner = package scala
[reflect-compiler] translating reflection info for Java class java.lang.StringBuffer
[reflect-compiler] translating reflection info for Java class java.util.Locale
[reflect-compiler] translating reflection info for Java class java.io.UnsupportedEncodingException
[reflect-compiler] made Scala package nio
[reflect-compiler] made Scala package charset
[reflect-compiler] translating reflection info for Java class java.nio.charset.Charset
[reflect-compiler] translating reflection info for Java class java.lang.StringBuilder
[reflect-compiler] translating reflection info for Java interface java.lang.Comparable
[reflect-compiler] made Scala package beans
parsing com.test.Outer.Inner.VAL
importing com.test.Outer.Inner.VAL
compiling com.test.Outer.Inner.VAL
[reflect-compiler] unpickling Scala class Predef and object Predef, owner = package scala
[reflect-compiler] unpickling Scala class ClassfileAnnotation and object ClassfileAnnotation, owner = package annotation
[reflect-compiler] unpickling Scala class Annotation and object Annotation, owner = package annotation
[reflect-compiler] unpickling Scala class StaticAnnotation and object StaticAnnotation, owner = package annotation
[reflect-compiler] made Scala package reflect
[reflect-compiler] unpickling Scala package package and package reflect, owner = package reflect
[reflect-compiler] made Scala package api
[reflect-compiler] unpickling Scala package package and package api, owner = package api
[reflect-compiler] unpickling Scala class Universe and object Universe, owner = package api
[reflect-compiler] unpickling Scala class Symbols and object Symbols, owner = package api
[reflect-compiler] unpickling Scala class Types and object Types, owner = package api
[reflect-compiler] unpickling Scala class FlagSets and object FlagSets, owner = package api
[reflect-compiler] unpickling Scala class Scopes and object Scopes, owner = package api
[reflect-compiler] unpickling Scala class Names and object Names, owner = package api
[reflect-compiler] unpickling Scala class Trees and object Trees, owner = package api
[reflect-compiler] unpickling Scala class Constants and object Constants, owner = package api
[reflect-compiler] unpickling Scala class Annotations and object Annotations, owner = package api
[reflect-compiler] unpickling Scala class Positions and object Positions, owner = package api
[reflect-compiler] unpickling Scala class Exprs and object Exprs, owner = package api
[reflect-compiler] unpickling Scala class TypeTags and object TypeTags, owner = package api
[reflect-compiler] unpickling Scala class TagInterop and object TagInterop, owner = package api
[reflect-compiler] unpickling Scala class StandardDefinitions and object StandardDefinitions, owner = package api
[reflect-compiler] unpickling Scala class StandardNames and object StandardNames, owner = package api
[reflect-compiler] unpickling Scala class BuildUtils and object BuildUtils, owner = package api
[reflect-compiler] unpickling Scala class Mirrors and object Mirrors, owner = package api
[reflect-compiler] unpickling Scala class Printers and object Printers, owner = package api
[reflect-compiler] unpickling Scala class Importers and object Importers, owner = package api
[reflect-compiler] made Scala package runtime
[reflect-compiler] unpickling Scala package package and package runtime, owner = package runtime
[reflect-compiler] unpickling Scala class StringContext and object StringContext, owner = package scala
[reflect-compiler] unpickling Scala class Product and object Product, owner = package scala
[reflect-compiler] unpickling Scala class Equals and object Equals, owner = package scala
[reflect-compiler] unpickling Scala class Serializable and object Serializable, owner = package scala
[reflect-compiler] made Scala package immutable
[reflect-compiler] unpickling Scala package package and package immutable, owner = package immutable
[reflect-compiler] unpickling Scala class Array and object Array, owner = package scala
[reflect-compiler] translating reflection info for Java interface java.lang.Cloneable
[reflect-compiler] unpickling Scala class AnyVal and object AnyVal, owner = package scala
[reflect-compiler] unpickling Scala class NotNull and object NotNull, owner = package scala
[reflect-compiler] unpickling Scala class LowPriorityImplicits and object LowPriorityImplicits, owner = package scala
[reflect-compiler] made Scala package com
[reflect-compiler] unpickling Scala class Dynamic and object Dynamic, owner = package scala
[reflect-compiler] made Scala package test
[reflect-compiler] translating reflection info for Java class com.test.Outer
[reflect-compiler] *** missing: Inner/true/object Outer/false/class scala.reflect.runtime.SynchronizedOps$$anon$1
java.lang.Exception
    at scala.tools.nsc.typechecker.Contexts$Context.issue(Contexts.scala:399)
    at scala.tools.nsc.typechecker.ContextErrors$ErrorUtils$.issueTypeError(ContextErrors.scala:84)
    at scala.tools.nsc.typechecker.ContextErrors$ErrorUtils$.issueNormalTypeError(ContextErrors.scala:69)
    at scala.tools.nsc.typechecker.ContextErrors$TyperContextErrors$TyperErrorGen$.NotAMemberError(ContextErrors.scala:331)
    at scala.tools.nsc.typechecker.Typers$Typer.handleMissing$1(Typers.scala:4846)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedSelect$1(Typers.scala:4851)
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelectOrSuperCall$1(Typers.scala:4938)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5551)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630)
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5710)
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5716)
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelectOrSuperCall$1(Typers.scala:4918)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5551)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630)
    at scala.tools.nsc.typechecker.Typers$Typer.transformedOrTyped(Typers.scala:5825)
    at scala.tools.nsc.typechecker.Typers$Typer.typedDefDef(Typers.scala:2250)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5557)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2921)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025)
    at scala.collection.immutable.List.loop$1(List.scala:170)
    at scala.collection.immutable.List.mapConserve(List.scala:186)
    at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3025)
    at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1914)
    at scala.tools.nsc.typechecker.Typers$Typer.typedModuleDef(Typers.scala:1794)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5572)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2921)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025)
    at scala.collection.immutable.List.loop$1(List.scala:170)
    at scala.collection.immutable.List.mapConserve(List.scala:186)
    at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3025)
    at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:5288)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5575)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5687)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:99)
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:463)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:91)
    at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1582)
    at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1556)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:251)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416)
    at Issue$delayedInit$body.apply(Issue.scala:8)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    at scala.App$class.main(App.scala:71)
    at Issue$.main(Issue.scala:3)
    at Issue.main(Issue.scala)
Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has failed: 

[namer in 31ms]
[packageobjects in 0ms]
value Inner is not a member of object com.test.Outer
[typer in 211ms]
[total in 247ms]
[reset] recursing in package <root>
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:319)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:252)
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416)
    at Issue$delayedInit$body.apply(Issue.scala:8)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    at scala.App$class.main(App.scala:71)
    at Issue$.main(Issue.scala:3)
    at Issue.main(Issue.scala)

编辑 2

我认为这是反射 API 中的错误,但我不确定。 我调试了输入阶段并得出以下结果:

在为 com.test.Outer 分配了适当的符号后,我们进入了 com.test.Outer.Inner 的输入阶段。

它使用 scala.reflect.internal.Scopes.Scope#lookupEntry(Name) 查找 Inner 的符号。

检查查看的作用域表明它确实包含 InnerClassSymbolScopeEntry 但作用域符号名称之间的相等性测试和方法 name 参数是使用 Object#equals 完成的(即 equals 没有被覆盖), 并且两个名称实例不相同。

关于交易品种名称和传递的名称参数的最后一点是,我看到它们具有相同的 index 字段。我不确定这是什么意思,但我的印象是这意味着它们在名称表中引用相同的名称,所以它们相等(?) (虽然两者之间有一个区别,一个是 TermName,而符号的名称是 TypeName)。

无论如何,我可能会打开一个 Scala 的错误跟踪器,只是想在这里总结一下。

最佳答案

正确 - 看起来 Scala/JVM 反射 API 无法确定 VAR 是嵌套内部类的静态成员。

关于java - 引用内部静态 Java 类时工具箱编译的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16014513/

相关文章:

Java泛型练习——答案解释

java - 有没有办法使用Java的Override注释来指定被覆盖的接口(interface)/类?

java - 当订阅者需要主消息类型的子类时,观察者模式就不够用了,替代方案?

scala - 在Scala中计算素数: how does this code work?

c# - 是否有可以与传入的 KeyEventArgs 匹配的热键的 .NET 类?

c# - 如何创建和访问在 C# 中作为参数传递的匿名类的新实例?

java - 使用 Elasticsearch API 实现不等于

scala - 如何在 Scala 中覆盖 Java varargs 方法?

scala 迭代匹配,奇怪的编译器错误

reflection - 路径相关类型与 "underlying types",检查哪些类型?