Spec-Zone.ru › Scala 2.13 Reflection

Трейт scala.reflect.api.Mirrors

trait Mirrors extends AnyRef

ЭКСПЕРИМЕНТАЛЬНО

Этот трейт предоставляет поддержку для зеркал (Mirrors) в API Scala Reflection.

Mirror являются центральной частью Scala Reflection. Вся информация, предоставляемая рефлексией, доступна через Mirror. В зависимости от типа получаемой информации или выполняемого рефлексивного действия, необходимо использовать разные типы зеркал. Зеркала "загрузчика классов" могут использоваться для получения представлений о типах и членах. Из загрузчика Mirror, можно получить более специализированные зеркала "вызывающие" Mirror (наиболее часто используемые), которые реализуют рефлексивные вызовы, такие как вызовы методов/конструкторов и доступ к полям.

Два типа зеркал:

  • Зеркала "загрузчика классов". Эти зеркала переводят имена в символы (через методы staticClass/staticModule/staticPackage).
  • Зеркала "вызывающие". Эти зеркала реализуют рефлексивные вызовы (через методы MethodMirror.apply, FieldMirror.get, и т.д.). Эти "вызывающие" зеркала являются наиболее часто используемыми типами зеркал.
Зеркала времени компиляции

Зеркала времени компиляции Mirror используют только зеркала загрузчика классов Mirror для загрузки Symbol по имени.

Точкой входа в зеркала загрузчика классов Mirror является scala.reflect.macros.blackbox.Context#mirror или scala.reflect.macros.whitebox.Context#mirror. Типичные методы, использующие зеркала загрузчика классов Mirror включают scala.reflect.api.Mirror#staticClass, scala.reflect.api.Mirror#staticModule и scala.reflect.api.Mirror#staticPackage. Например:

import scala.reflect.macros.blackbox.Context

case class Location(filename: String, line: Int, column: Int)

object Macros {
  def currentLocation: Location = macro impl

  def impl(c: Context): c.Expr[Location] = {
    import c.universe._
    val pos = c.macroApplication.pos
    val clsLocation = c.mirror.staticModule("Location") // get symbol of "Location" object
    c.Expr(Apply(Ident(clsLocation), List(Literal(Constant(pos.source.path)), Literal(Constant(pos.line)), Literal(Constant(pos.column)))))
  }
}

Важно: Существуют несколько альтернатив высокого уровня, которые можно использовать, чтобы избежать ручного поиска символов. Например, typeOf[Location.type].termSymbol (или typeOf[Location].typeSymbol если нам нужно ClassSymbol), которые являются безопасными с точки зрения типов, так как нам не нужно использовать String для поиска Symbol.

Зеркала времени выполнения

Зеркала времени выполнения Mirror используют как зеркала загрузчика классов, так и вызывающие зеркала Mirror.

Точкой входа в зеркала Mirror для использования во время выполнения является ru.runtimeMirror(<classloader>), где ru это scala.reflect.runtime.universe.

Результат вызова scala.reflect.api.JavaUniverse#runtimeMirror — это зеркало загрузчика классов, типа scala.reflect.api.Mirrors#ReflectiveMirror, которое может загружать символы по именам, как описано выше (в разделе "Время компиляции").

Зеркало загрузчика классов может создавать вызывающие зеркала, включающие: scala.reflect.api.Mirrors#InstanceMirror, scala.reflect.api.Mirrors#MethodMirror, scala.reflect.api.Mirrors#FieldMirror, scala.reflect.api.Mirrors#ClassMirror и scala.reflect.api.Mirrors#ModuleMirror.

Примеры того, как эти два типа Mirror взаимодействуют, приведены ниже.

Типы зеркал, их применение и примеры

scala.reflect.api.Mirrors#ReflectiveMirror. Используется для загрузки Symbol по имени и как точка входа в вызывающие зеркала. Точка входа: val m = ru.runtimeMirror(<classloader>). Пример:

scala> val ru = scala.reflect.runtime.universe
ru: scala.reflect.api.JavaUniverse = ...

scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror ...

scala.reflect.api.Mirrors#InstanceMirror. Используется для создания вызывающих зеркал Mirror для методов и полей, а также для внутренних классов и внутренних объектов (модулей). Точка входа: val im = m.reflect(<value>). Пример:

scala> class C { def x = 2 }
defined class C

scala> val im = m.reflect(new C)
im: reflect.runtime.universe.InstanceMirror = instance mirror for C@3442299e

scala.reflect.api.Mirrors#MethodMirror. Используется для вызова методов экземпляров (в Scala есть только методы экземпляров — методы объектов являются методами экземпляров объектов, доступными через ModuleMirror.instance). Точка входа: val mm = im.reflectMethod(<method symbol>). Пример:

scala> val methodX = typeOf[C].decl(TermName("x")).asMethod
methodX: reflect.runtime.universe.MethodSymbol = method x

scala> val mm = im.reflectMethod(methodX)
mm: reflect.runtime.universe.MethodMirror = method mirror for C.x: scala.Int (bound to C@3442299e)

scala> mm()
res0: Any = 2

scala.reflect.api.Mirrors#FieldMirror. Используется для получения/установки полей экземпляров (в Scala есть только поля экземпляров — поля объектов являются методами экземпляров объектов, доступными через ModuleMirror.instance). Точка входа: val fm = im.reflectMethod(<field or accessor symbol>). Пример:

scala> class C { val x = 2; val y = 3 }
defined class C

scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror ...

scala> val im = m.reflect(new C)
im: reflect.runtime.universe.InstanceMirror = instance mirror for C@5f0c8ac1

scala> val fieldX = typeOf[C].decl(TermName("x")).asTerm.accessed.asTerm
fieldX: reflect.runtime.universe.TermSymbol = value x
scala> val fmX = im.reflectField(fieldX)
fmX: reflect.runtime.universe.FieldMirror = field mirror for C.x (bound to C@5f0c8ac1)

scala> fmX.get
res0: Any = 2

scala> fmX.set(3) // NOTE: can set an underlying value of an immutable field!

scala> val fieldY = typeOf[C].decl(TermName("y")).asTerm.accessed.asTerm
fieldY: reflect.runtime.universe.TermSymbol = variable y

scala> val fmY = im.reflectField(fieldY)
fmY: reflect.runtime.universe.FieldMirror = field mirror for C.y (bound to C@5f0c8ac1)

scala> fmY.get
res1: Any = 3

scala> fmY.set(4)

scala> fmY.get
res2: Any = 4

scala.reflect.api.Mirrors#ClassMirror. Используется для создания вызывающих зеркал для конструкторов. Точки входа: для статических классов val cm1 = m.reflectClass(<class symbol>), для внутренних классов val mm2 = im.reflectClass(<class symbol>). Пример:

scala> case class C(x: Int)
defined class C

scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror ...

scala> val classC = typeOf[C].typeSymbol.asClass

classC: reflect.runtime.universe.Symbol = class C

scala> val cm = m.reflectClass(classC)
cm: reflect.runtime.universe.ClassMirror = class mirror for C (bound to null)

scala> val ctorC = typeOf[C].decl(ru.nme.CONSTRUCTOR).asMethod
ctorC: reflect.runtime.universe.MethodSymbol = constructor C

scala> val ctorm = cm.reflectConstructor(ctorC)
ctorm: reflect.runtime.universe.MethodMirror = constructor mirror for C.<init>(x: scala.Int): C (bound to null)

scala> ctorm(2)
res0: Any = C(2)

scala.reflect.api.Mirrors#ModuleMirror. Используется для получения одиночных экземпляров объектов. Точки входа: для статических объектов (модулей) val mm1 = m.reflectModule(<module symbol>), для внутренних объектов (модулей) val mm2 = im.reflectModule(<module symbol>). Пример:

scala> object C { def x = 2 }
defined module C

scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror ...

scala> val objectC = typeOf[C.type].termSymbol.asModule
objectC: reflect.runtime.universe.ModuleSymbol = object C

scala> val mm = m.reflectModule(objectC)
mm: reflect.runtime.universe.ModuleMirror = module mirror for C (bound to null)

scala> val obj = mm.instance
obj: Any = C$@1005ec04

Для получения дополнительной информации о Mirrors см. Руководство по рефлексии: Зеркала

Self Type
Universe
Source
Mirrors.scala
Линейные надтипы
AnyRef, Any
Известные подклассы
JavaUniverse, Universe, Universe

Члены типа

тракт ClassMirror extends Universe.TemplateMirror

Зеркало, отражающее части экземпляра класса в среде выполнения. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

тракт FieldMirror extends AnyRef

Зеркало, отражающее поле. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

тракт InstanceMirror extends AnyRef

Зеркало, отражающее значение в среде выполнения. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

тракт MethodMirror extends AnyRef

Зеркало, отражающее метод. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

абстрактный тип Mirror >: Null <: api.Mirror[Mirrors.this.type]

Базовый тип всех зеркал этого универсума.

Этот абстрактный тип соответствует базовому интерфейсу для всех зеркал, определённых в scala.reflect.api.Mirror, и постепенно уточняется в конкретных универсумах (например, Mirror scala.reflect.api.JavaUniverse способен к рефлексии).

тракт ModuleMirror extends Universe.TemplateMirror

Зеркало, отражающее определение Scala-объекта или статические части класса в среде выполнения. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

тракт ReflectiveMirror extends api.Mirror[Mirrors.this.type]

Зеркало, отражающее экземпляры и статические классы. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

абстрактный тип RuntimeClass >: Null <: AnyRef

тракт RuntimeClassApi extends AnyRef

Не имеет специальных методов. Присутствует для предоставления стёртой идентичности для RuntimeClass.

тракт RuntimeMirror extends api.Mirror[Mirrors.this.type] with Universe.ReflectiveMirror

API зеркала для рефлексивного универсума. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

тракт TemplateMirror extends AnyRef

Зеркало, отражающее экземпляры или статические части класса в среде выполнения. См. страницу обзора для получения подробностей о том, как использовать рефлексию в среде выполнения.

Абстрактные члены-значения

абстрактный val rootMirror: Universe.Mirror

Корневое зеркало этого универсума. Это зеркало содержит стандартные классы и типы Scala, такие как Any, AnyRef, AnyVal, Nothing, Null, и все классы, загруженные из scala-library, которые общие для всех зеркал в содержащем универсуме.

Члены конкретных значений

final def !=(arg0: Any): Boolean

Определяющие классы
AnyRef → Any

final def ##(): Int

Определяющие классы
AnyRef → Any

def +(other: String): String

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вany2stringadd[Mirrors] выполненного методом any2stringadd в scala.Predef.
Определяющие классы
any2stringadd

def ->[B](y: B): (Mirrors, B)

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вArrowAssoc[Mirrors] выполненного методом ArrowAssoc в scala.Predef.
Определяющие классы
ArrowAssoc
Аннотации
@inline()

final def ==(arg0: Any): Boolean

Определяющие классы
AnyRef → Any

final def asInstanceOf[T0]: T0

Определяющие классы
Any

def clone(): AnyRef

Атрибуты
protected[java.lang]
Определяющие классы
AnyRef
Аннотации
@throws(classOf[java.lang.CloneNotSupportedException]) @native()

def ensuring(cond: (Mirrors) => Boolean, msg: => Any): Mirrors

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вEnsuring[Mirrors] выполненного методом Ensuring в scala.Predef.
Определяющие классы
Ensuring

def ensuring(cond: (Mirrors) => Boolean): Mirrors

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вEnsuring[Mirrors] выполненного методом Ensuring в scala.Predef.
Определяющие классы
Ensuring

def ensuring(cond: Boolean, msg: => Any): Mirrors

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вEnsuring[Mirrors] выполненного методом Ensuring в scala.Predef.
Определяющие классы
Ensuring

def ensuring(cond: Boolean): Mirrors

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вEnsuring[Mirrors] выполненного методом Ensuring в scala.Predef.
Определяющие классы
Ensuring

final def eq(arg0: AnyRef): Boolean

Определяющие классы
AnyRef

def equals(arg0: AnyRef): Boolean

Определяющие классы
AnyRef → Any

def finalize(): Unit

Атрибуты
protected[java.lang]
Определяющие классы
AnyRef
Аннотации
@throws(classOf[java.lang.Throwable])

def formatted(fmtstr: String): String

Неявный
Этот член добавлен с помощью неявного преобразования из Mirrors вStringFormat[Mirrors] выполненного методом StringFormat в scala.Predef.
Определяющие классы
StringFormat
Аннотации
@inline()

final def getClass(): Class[_ <: AnyRef]

Definition Classes
AnyRef → Any
Annotations
@native()

def hashCode(): Int

Definition Classes
AnyRef → Any
Annotations
@native()

final def isInstanceOf[T0]: Boolean

Definition Classes
Any

final def ne(arg0: AnyRef): Boolean

Definition Classes
AnyRef

final def notify(): Unit

Definition Classes
AnyRef
Annotations
@native()

final def notifyAll(): Unit

Definition Classes
AnyRef
Annotations
@native()

final def synchronized[T0](arg0: => T0): T0

Definition Classes
AnyRef

def toString(): String

Definition Classes
AnyRef → Any

final def wait(): Unit

Definition Classes
AnyRef
Annotations
@throws(classOf[java.lang.InterruptedException])

final def wait(arg0: Long, arg1: Int): Unit

Definition Classes
AnyRef
Annotations
@throws(classOf[java.lang.InterruptedException])

final def wait(arg0: Long): Unit

Definition Classes
AnyRef
Annotations
@throws(classOf[java.lang.InterruptedException]) @native()

© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.13.0/scala-reflect/scala/reflect/api/Mirrors.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API