Scala反射API
反射创建 Object单例
package demo
object A {
val i = 1
}
通过 java 常规的方式是不行的
val clazz = Class.forName("demo.A")
val constructors: Array[Constructor[_]] = clazz.getConstructors
val declaredConstructors: Array[Constructor[_]] = clazz.getDeclaredConstructors
println(constructors.length) // 0
println(declaredConstructors.length) // 0
object编译后会生成下面两个类:A.class 和 A$.class,使用 jd-gui 反编译后是下面这样子:
package demo;
public final class A$
{
public static final A$ MODULE$ = new A$();
}
package demo;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\005M9Qa\001\003\t\002\0351Q!\003\003\t\002)AQ!E\001\005\
002I\t\021!\021\006\002\013\005!A-Z7p\007\001\001\"\001C\001\016\003\021\021\021!Q\n\003\
003-\001\"\001D\b\016\0035Q\021AD\001\006g\016\fG.Y\005\003!5\021a!\0218z%\0264\027A\002\0
37j]&$h\bF\001\b\001")
public final class A {}
A 这个类没有默认构造函数,甚至没有任何构造函数,所以这么用反射是创建不了的。
好在Scala 实现了自己的反射库:scala-reflect,使用时需要引入单独的 jar 包:
// https://mvnrepository.com/artifact/org.scala-lang/scala-reflect
libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.13.0"
// https://mvnrepository.com/artifact/org.scala-lang/scala-library
libraryDependencies += "org.scala-lang" % "scala-library" % "2.13.0"
Scala 的单例对象(Object)是特殊的单例实例,反射时需通过其类型符号直接获取实例。这么拿到的object实例并非直觉上以为的单例对象 demo.A,实际上是 demo.A$。
import scala.reflect.runtime.universe
val mirror = universe.runtimeMirror(getClass.getClassLoader)
// 注意用 staticModule 而非 staticClass
val objectSymbol = mirror.staticModule("demo.A")
// 2. 获取单例对象的镜像(直接获取实例)
val objectMirror = mirror.reflectModule(objectSymbol)
// 3. 获取实例
val instance = objectMirror.instance.asInstanceOf[A.type]
println(instance) // demo.A$@535779e4, 实际上是 A$ 类
println(instance.i) // 1
反射创建 Class实例
package demo
import scala.reflect.runtime.{universe => ru}
class MyClass(val name: String, val age: Int) {
def greet(): Unit = println(s"Hello, I'm $name, $age years old")
}
object ReflectDemo {
def main(args: Array[String]): Unit = {
// 获取运行时镜像
val mirror = ru.runtimeMirror(getClass.getClassLoader)
// 1. 获取类的类型符号(需要类的全限定名)
val classSymbol = mirror.staticClass("demo.MyClass")
// 2. 获取类的构造器(默认获取主构造器)
val constructorSymbol = classSymbol.primaryConstructor.asMethod
// 3. 获取类的
val classMirror = mirror.reflectClass(classSymbol)
// 4. 获取构造器方法
val constructor = classMirror.reflectConstructor(constructorSymbol)
// 5. 调用构造器创建实例
val instance = constructor("Alice", 30).asInstanceOf[MyClass]
println(instance.getClass) // class demo.MyClass
instance.greet()
}
}

浙公网安备 33010602011771号