Java/Scala 反射 : Get class methods in order and force object init

标签 java scala reflection phantom-dsl

我有一个,其中有一些对象作为内部方法。

我也问了this question不久前得到了一个很好的答案,但这会导致 servlet 容器中出现 fatal error 。当 URLClassLoader 请求类时,Scala 无法始终如一地生成 TypeTag

有问题的项目是开源的,找到here .

目前找到的方法是here ,但它不保留顺序。对象成员已正确初始化,但顺序是随机的。

问题:如何收集类(class)成员:

  • 按照定义的顺序
  • 以线程安全的方式
  • 按父类(super class)型过滤它们
  • 贪心初始化对象(引用module.instance) ?

更新:

  • 不要根据此处的链接建议答案,它们已经过测试并且已知会失败。
  • 出于风格原因,使用 val 而不是 object 不是一种选择。
  • 众所周知,
  • getMethodsgetDeclaredFields 不能保证顺序。如果这在某种程度上是可能的,那么很可能是 Scala 反射。

最佳答案

来自 http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getDeclaredFields() :

public Field[] getDeclaredFields() throws SecurityException

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields. The elements in the array returned are not sorted and are not in any particular order. This method returns an array of length 0 if the class or interface declares no fields, or if this Class object represents a primitive type, an array class, or void. See The Java Language Specification, sections 8.2 and 8.3.

(我的重点)。 getDeclaredMethods() 的文档中有明确的类似语言,但 getDeclaredClasses() 的文档中没有(但 IMO 可以被认为是隐含的)。

所以不,您不能依赖 JVM 上的 Java 反射进行排序;在实践中,我发现顺序因运行的 JVM 架构(32 位与 64 位)而异。

如果您真的必须以特定顺序初始化对象(为什么?),您可以使用命名约定并手动排序;但是,最好将代码更改为与顺序无关。

更新

看来您可以从 Scala 反射 API 中获得一些东西:

trait EarlyInit {
  val mirror = runtimeMirror(this.getClass.getClassLoader)
  val reflection  = mirror.reflect(this)

  mirror
    .classSymbol(this.getClass)
    .toType
    .members
    .sorted    /// This method is documented to return members "in declaration order"
    .filter(_.isModule)
    .foreach(m => reflection.reflectModule(m.asModule).instance)
  }
}

参见 the API docs :

Sorts the symbols included in this scope so that: 1) Symbols appear in the linearization order of their owners. 2) Symbols with the same owner appear in same order of their declarations. 3) Synthetic members (e.g. getters/setters for vals/vars) might appear in arbitrary order.

但是,这不能保证在一般情况下工作,特别是对于混合 Java/Scala 项目(因为确实没有办法按声明顺序获取 Java 类的成员)。另外,请注意 Scala 运行时反射不是线程安全的,通常不被视为生产就绪。

我仍然认为将您的设计修改为独立于顺序会更好地为您服务,可能通过以不同方式编码依赖项。

关于Java/Scala 反射 : Get class methods in order and force object init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22405801/

相关文章:

c# - 如何在C#中使用反射从可执行文件(.exe)中提取类和方法信息

java - 使用未知参数长度调用未知构造函数

java - "com.mongodb.MongoSocketReadException"和 "com.mongodb.MongoTimeoutException"的解决方案是什么

java - 尝试解析 XML 字符串时没有向我抛出协议(protocol)格式错误的 URL 异常

eclipse - 如何手动安装 Scala 插件?

scala - 为什么 Play 框架不重新加载资源?

java - Java 项目中 int 数组出现 NullPointerException

java - Spring MVC 和 JSR 303

scala - Akka-http:接受和内容类型处理

java - 如何从文件系统加载任意 java .class 文件并对其进行反射(reflect)?