如何从Java访问Scala包对象中定义的Case Class?
在Java中访问Scala包对象里的Case Class的正确方式
你遇到的问题其实是Scala和Java互操作时的一个常见误区——你误以为包对象里的case class是包对象单例的成员,但实际上Scala编译器会把这些case class编译成对应包下的独立顶级类,所以不能通过package$.MODULE$来访问它们。
为什么你的调用方式会失败?
com.github.somepkg.reactiveconfig.package$.MODULE$是Scala包对象的单例实例,它只包含包对象里定义的方法、变量等成员。而你定义的Value和ParsedKeyValue是独立的类定义,不属于这个单例对象的成员,所以自然无法通过MODULE$.Value(...)这种方式调用。
正确的Java访问方式
你可以直接通过case class的全限定类名来实例化,有两种常用方式:
1. 直接调用构造器
Scala的case class会自动生成对应的Java构造器,你可以像普通Java类一样new出来:
// 实例化Value类 com.github.somepkg.reactiveconfig.Value<String> value = new com.github.somepkg.reactiveconfig.Value<>("your-parsed-data", 22L); // 实例化ParsedKeyValue类 com.github.somepkg.reactiveconfig.ParsedKeyValue<String> parsedKV = new com.github.somepkg.reactiveconfig.ParsedKeyValue<>("config-key", value);
2. 调用Scala生成的静态apply方法
Case class在Scala中会自动生成apply工厂方法,这个方法在Java中会被编译成静态方法,你也可以直接调用:
// 用apply方法创建Value实例 com.github.somepkg.reactiveconfig.Value<String> value = com.github.somepkg.reactiveconfig.Value.apply("your-parsed-data", 22L); // 用apply方法创建ParsedKeyValue实例 com.github.somepkg.reactiveconfig.ParsedKeyValue<String> parsedKV = com.github.somepkg.reactiveconfig.ParsedKeyValue.apply("config-key", value);
补充说明
不管是case class还是普通类,只要定义在Scala的package object里,编译后都会成为对应包下的独立顶级类,和包对象的单例实例是平级的关系,所以直接通过全类名访问就好,不用绕到MODULE$里。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

