设为首页 加入收藏

TOP

Scala Reflection - Mirrors,ClassTag,TypeTag and WeakTypeTag(一)
2017-10-10 12:10:51 】 浏览:2904
Tags:Scala Reflection Mirrors ClassTag TypeTag and WeakTypeTag

    反射reflection是程序对自身的检查、验证甚至代码修改功能。反射可以通过它的Reify功能来实时自动构建生成静态的Scala实例如:类(class)、方法(method)、表达式(expression)等。或者动态跟踪当前程序运算事件如:方法运算(method invocation)、字段引用(field access)等。反射又分编译时段与运算时段反射即:compile-time-reflection及runtime-reflection。我们使用compile-time-reflection在编译程序时指导编译器修改编译中代码或者产生新的代码,用runtime-reflection来进行实例的类型匹配、验证等。在v2.10之前,Scala没有自备的Reflection工具库,只能用Java Reflection库提供的部分功能来动态检验类型(class)或对象(object)及使用它们的字段(member access)。但java-reflection无法提供对某些scala项目的支持如:function、trait以及特殊类型如:existential、high-kinder、path-dependent、abstract types。特别是java-reflection无法获取泛类型在runtime过程中的信息,这个一直是一个诟病。直到scala2.10增加了新的reflection库才从根本上解决了针对scala特性的反射(refective)功能问题。scala-reflection同样提供了compile-time-reflection和runtime-reflection。其中compile-time-reflection是通过独立的macro库实现的。在这篇讨论里我们主要介绍runtime-reflection功能。

scala runtime-reflection有以下几项主要功能:

1、动态检验对象类型,包括泛类型

2、实时构建类型实例

3、实时调用类型的运算方法

反射功能可以在两种环境下体现:compile-time及runtime,是通过反射库的universe命名空间分辨的,即:

runtime-reflection     : scala.reflect.runtime.universe

compile-time-reflection: scala.reflect.macros.universe

我们必须import相应的命名空间来获取compile-time或runtime反射功能。

各种具体的runtime反射功能是通过Mirror来获取的,以runtimeMirror(...)为入口。下面是各种Mirror的获取和使用方法示范:

 1  val ru = scala.reflect.runtime.universe  2   //runtime reflection入口
 3   val m = ru.runtimeMirror(getClass.getClassLoader)  //m: ru.Mirror = JavaMirror with java.net.URLClassLoader...  4   //sample class
 5   class Person(name: String, age: Int) {  6     var hight: Double = 0.0
 7     def getName = name  8  }  9   val john = new Person("John", 23) { 10     hight = 1.7
11  } 12   //instance mirror
13   val im = m.reflect(john) 14   //im: ru.InstanceMirror = instance mirror for... 15   //query method on instance
16   val mgetName = ru.typeOf[Person].decl(ru.TermName("getName")).asMethod 17   //mgetName: ru.MethodSymbol = method getName 18   //get method
19   val invoke_getName = im.reflectMethod(mgetName) //invoke_getName: ru.MethodMirror = ...
20  invoke_getName() 21   //res0: Any = John 22   //query field on instance
23   val fldHight = ru.typeOf[Person].decl(ru.TermName("hight")).asTerm 24   //fldHight: ru.TermSymbol = variable hight 25   //get field
26   val fmHight = im.reflectField(fldHight) //fmHight: ru.FieldMirror = ...
27   fmHight.get //res1: Any = 1.7
28   fmHight.set(1.6) 29   fmHight.get
30   //res3: Any = 1.6
31   val clsP = ru.typeOf[Person].typeSymbol.asClass 32   //get class mirror
33   val cm = m.reflectClass(clsP) 34   //get constructor symbol
35   val ctorP = ru.typeOf[Person].decl(ru.nme.CONSTRUCTOR).asMethod 36   //get contructor mirror
37   val ctorm = cm.reflectConstructor(ctorP) 38   val mary = ctorm("mary", 20).asInstanceOf[Person] 39   println(mary.getName)    // mary
40   object OB { 41     def x = 3
42  } 43   //get object symbol
44   val objOB = ru.typeOf[OB.type].termSymbol.asModule 45   //get module mirror
46   val mOB = m.reflectModule(objOB) 47   //get object instance
48   val instOB = mOB.instance.asInstanceOf[OB.type] 49   println(instOB.x)  // 3

上面例子里的typeOf[T]和typeTag[T].tpe及implicitly[TypeTag[T]].tpe是通用的,看下面的示范: 

1   val clsP = ru.typeTag[Person].tpe.typeSymbol.asClass  //ru.typeOf[Person].typeSymbol.asClass
2   val clsP1 = implicitly[ru.TypeTag[Person]].tpe.typeSymbol.asClass //clsP1: ru.ClassSymbol = class Person
3   val clsP2 = ru.typeTag[Person].tpe.t
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scala--操作符 下一篇scala学习之第三天:数组的特性与..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目