如何在Java中传递嵌套的scala对象引用?

时间:2016-11-23 23:52:58

标签: java scala interop

以前有过一些问题的答案。

但我的问题是我有嵌套的scala对象,例如:

object Criteria {
    object ActionCriteria {
        case class Action (parameter: String) {
            def this(parameter: String) = { this(paramerter) }
        }

        object Action {
           def apply(parameter: String): Action = { apply(parameter) }
        } 
    }
}

在java中,我需要创建一个Actions列表。我试过这个......无济于事:

import Criteria.ActionCriteria.Action$

....

List<Criteria.ActionCriteria.Action$.MODULE$> actions = new ArrayList<>();

还有许多其他组合,比如在每个对象中添加$ .MODULE $。现在我收到以下错误:

error: cannot find symbol Criteria.ActionCriteria

1 个答案:

答案 0 :(得分:3)

List<Criteria$ActionCriteria$Action> actions = new ArrayList<>();

似乎工作正常。使用Scala REPL找到了这个:

scala> classOf[Criteria.ActionCriteria.Action]
res1: Class[Criteria.ActionCriteria.Action] = class Criteria$ActionCriteria$Action

如果你想要Action对象的类型,而不是案例类(极不可能,但为了完整性):

scala> Criteria.ActionCriteria.Action.getClass
res2: Class[_ <: Criteria.ActionCriteria.Action.type] = class Criteria$ActionCriteria$Action$

这种差异是由Scala期望Action成为classOf[Action]中的类型引起的,因此它返回与case类对应的类型。在期望值的上下文中使用Action时,它会返回单例实例,因此您可以调用标准Java方法getClass来获取object Action的类型。

如果您需要其他类型:

Criteria$                       cm    = Criteria$.MODULE$;
Criteria.ActionCriteria$        cacm  = Criteria.ActionCriteria$.MODULE$;
Criteria$ActionCriteria$Action$ cacam = Criteria$ActionCriteria$Action$.MODULE$;
Criteria$ActionCriteria$Action  caca  = new Criteria$ActionCriteria$Action("Foo");

Criteria.ActionCriteria$打破了这里的模式。为什么?根据Iulian Dragos的说法。 bug SI-2034下的评论这是一个特例:

  

因为对象是&#34;相当于静态&#34;在Java世界中,我们   希望Java代码更容易使用静态内部类。   如果只有一个级别的嵌套,那么就有保证   伴侣:每个顶级对象都有一个镜像类(如果没有的话)   一)为模块方法创建静态转发器(这是一个方法   可以运行在对象内定义的main方法。因此,一个   一级嵌套的特殊情况:这些类使用扁平化   name(没有$后缀)作为outer_name。所以,Java代码可以说new Outer.Inner

摘要

  • 对于除了第一个之外的每个嵌套级别,您在班级名称中将.替换为$

  • 如果目标类型也是您在末尾添加$的对象

  • 如果您想要添加.MODULE$

  • 的实例