Spec-Zone.ru › Scala 2.13 Library

Пакет scala.annotation

пакет annotation

Члены пакета

пакет meta

При определении поля компилятор Scala создаёт до четырёх аксессоров: геттер, сеттер, а если поле анотировано с помощью @BeanProperty, то ещё и бино-геттер и бино-сеттер.

Например, в следующем определении класса

class C(@myAnnot @BeanProperty var c: Int)

есть шесть сущностей, которые могут содержать анотацию @myAnnot: параметр конструктора, сгенерированное поле и четыре аксессора.

По умолчанию, анотации на (val-, var- или простых) параметрах конструктора сохраняются на параметре, а не на других сущностях. Анотации на полях по умолчанию сохраняются только на поле.

Мета-анотации в пакете scala.annotation.meta используются для управления тем, где анотации на полях и параметрах класса копируются. Это делается путём аннотации типа анотации или класса анотации одной или несколькими мета-анотациями в этом пакете.

Аннотация типа анотации

Мета-анотации назначения могут быть помещены на тип анотации при создании экземпляра анотации. В следующем примере, анотация @Id будет добавлена только к бино-геттеру getX.

import javax.persistence.Id
class A {
  @(Id @beanGetter) @BeanProperty val x = 0
}

Для аннотации поля также потребуется добавить мета-анотацию @field.

Синтаксис можно улучшить, используя псевдоним типа:

object ScalaJPA {
  type Id = javax.persistence.Id @beanGetter
}
import ScalaJPA.Id
class A {
  @Id @BeanProperty val x = 0
}

Аннотация класса анотации

Для анотаций, определённых в Scala, можно указать целевое назначение в самом классе анотации, например

@getter
class myAnnotation extends Annotation

Это только изменяет целевое назначение по умолчанию для анотации myAnnotation. При создании экземпляра анотации целевое назначение всё ещё можно указать, как описано в предыдущем разделе.

пакет unchecked

Члены типа

абстрактный класс Annotation extends AnyRef

Базовый класс для аннотаций.

Аннотации, непосредственно наследующие этот класс, не сохраняются в файле класса. Для включения возможности хранения аннотаций в сигнатуре класса Scala и обеспечения доступа к ним для рефлексии Scala и других инструментов, аннотация должна наследоваться от scala.annotation.StaticAnnotation.

Аннотации, определенные в Scala, не хранятся в файлах классов в формате, совместимом с Java, и поэтому не видны в рефлексии Java. Для достижения этого аннотация должна быть написана на Java.

Since

2.4

тракт ConstantAnnotation extends Annotation with StaticAnnotation

Классы аннотаций, расширяющие этот тракт, принимают только константные значения в качестве аргументов.

Обратите внимание, что этот тракт наследуется от StaticAnnotation, поэтому константные аннотации сохраняются в файле класса.

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

Константные аннотации могут использовать аргументы по умолчанию. Обратите внимание, что внутреннее представление использования аннотации (которое видно, например, для плагинов компилятора) содержит только явно указанные аргументы.

Константные аннотации не могут определять вспомогательные конструкторы, и основной конструктор должен иметь единственный список параметров.

Пример:

class Ann(value: Int, x: Int = 0) extends scala.annotation.ConstantAnnotation
class Test {
  def someInt = 0
  @Ann(value = 0, x = 1) def g = 0
  @Ann(0) def f = 0                 // Internal representation contains `@Ann(value = 0)`
  @Ann(someInt)                     // error: argument needs to be a compile-time constant
}

тракт StaticAnnotation extends Annotation

Базовый класс для статических аннотаций. Они доступны для проверки типов Scala или рефлексии Scala даже в разных единицах компиляции.

Аннотации, определенные в Scala, не хранятся в файлах классов в формате, совместимом с Java, и поэтому не видны в рефлексии Java. Для достижения этого аннотация должна быть написана на Java.

Since

2.4

тракт TypeConstraint extends Annotation

Маркер для аннотаций, которые при применении к типу должны рассматриваться как ограничение на аннотированный тип.

Правильное ограничение должно ограничивать тип только на основе информации, указанной в типе. Компилятор Scala может использовать это предположение для переписывания содержимого ограничения по мере необходимости. В отличие от этого, аннотация типа, смысл которой зависит от контекста, в котором она написана, не является правильным ограничением типа, и этот маркер не должен применяться. Компилятор Scala удалит такие аннотации в случаях, когда он перепишет ограничение типа.

Since

2.6

final класс compileTimeOnly extends Annotation with StaticAnnotation

Аннотация, обозначающая, что на annottee не следует ссылаться после проверки типов (включая расширение макросов).

Примеры потенциального использования: 1) annottee может появляться только в аргументах какого-либо другого макроса, который удалит его из AST во время расширения. 2) annottee — это макрос и должен был быть удален, поэтому, если этого не произошло, что-то пошло не так. (Полезно для лучшей поддержки новых макросов, например, макро-аннотаций, которые не могут быть расширены стандартным компилятором).

Аннотации
@getter() @setter() @beanGetter() @beanSetter() @companionClass() @companionMethod()
Since

2.11.0

final класс elidable extends Annotation with StaticAnnotation

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

Поведение зависит от передачи -Xelide-below <arg> в scalac. Вызовы методов, помеченных elidable (а также тело метода), будут опущены из сгенерированного кода, если приоритет, заданный аннотацией, ниже, чем заданный в командной строке.

@elidable(123)           // annotation priority
scalac -Xelide-below 456 // command line priority

Вызов метода будет заменен выражением, зависящим от типа удаленного выражения. В порядке убывания приоритета:

Unit            ()
Boolean         false
T <: AnyVal     0
T >: Null       null
T >: Nothing    Predef.???

Полный пример:

import scala.annotation._, elidable._
object Test extends App {
  def expensiveComputation(): Int = { Thread.sleep(1000) ; 172 }

  @elidable(WARNING) def warning(msg: String) = println(msg)
  @elidable(FINE) def debug(msg: String)      = println(msg)
  @elidable(FINE) def computedValue           = expensiveComputation()

  warning("Warning! Danger! Warning!")
  debug("Debug! Danger! Debug!")
  println("I computed a value: " + computedValue)
}
% scalac example.scala && scala Test
Warning! Danger! Warning!
Debug! Danger! Debug!
I computed a value: 172

// INFO lies between WARNING and FINE
% scalac -Xelide-below INFO example.scala && scala Test
Warning! Danger! Warning!
I computed a value: 0

Обратите внимание, что только конкретные методы могут быть помечены @elidable. Неаннотированный метод не удаляется, даже если он переопределяет/реализует метод с аннотацией.

Также обратите внимание, что статический тип определяет, какие аннотации учитываются:

import scala.annotation._, elidable._
class C { @elidable(0) def f(): Unit = ??? }
object O extends C { override def f(): Unit = println("O.f") }
object Test extends App {
  O.f()      // not elided
  (O: C).f() // elided if compiled with `-Xelide-below 1`
}
Since

2.8

final класс implicitAmbiguous extends Annotation with StaticAnnotation

Для настройки сообщения об ошибке, выводимого при поиске неявно заданного значения, найденного неоднозначно, используйте аннотацию @implicitAmbiguous хотя бы для одного неявно заданного значения. Предполагая, что неявное значение — это метод с параметрами типа X1,..., XN, сообщение об ошибке будет результатом замены всех вхождений ${Xi} в строке msg строкой представления соответствующего аргумента типа Ti.

Если собрано более одной аннотации @implicitAmbiguous, компилятор свободен выбрать любую из них для отображения.

Приятные ошибки могут направлять пользователей к исправлению импорта или даже объяснять, почему код намеренно не компилируется.

trait =!=[C, D]

implicit def neq[E, F] : E =!= F = null

@annotation.implicitAmbiguous("Could not prove ${J} =!= ${J}")
implicit def neqAmbig1[G, H, J] : J =!= J = null
implicit def neqAmbig2[I] : I =!= I = null

implicitly[Int =!= Int]
Аннотации
@getter()
Since

2.12.0

final класс implicitNotFound extends Annotation with StaticAnnotation

Чтобы настроить сообщение об ошибке, которое выводится, когда не удается найти неявное значение типа C[T1,..., TN], добавьте аннотацию @implicitNotFound к классу C. Предполагая, что C имеет параметры типа X1, ..., XN, сообщение об ошибке будет результатом замены всех вхождений ${Xi} в строке msg строковым представлением соответствующего аргумента типа Ti.

Аннотация также может быть применена к неявным параметрам. В этом случае ${Xi} может ссылаться на параметры типа в текущем области видимости. Сообщение @implicitNotFound об параметре имеет приоритет над сообщением об типе параметра.

import scala.annotation.implicitNotFound

@implicitNotFound("Could not find an implicit C[${T}, ${U}]")
class C[T, U]

class K[A] {
  def m[B](implicit c: C[List[A], B]) = 0
  def n[B](implicit @implicitNotFound("Specific message for C of list of ${A} and ${B}") c: C[List[A], B]) = 1
}

object Test {
  val k = new K[Int]
  k.m[String]
  k.n[String]
}

Компилятор выводит следующие сообщения об ошибках:

Test.scala:13: error: Could not find an implicit C[List[Int], String]
  k.m[String]
     ^
Test.scala:14: error: Specific message for C of list of Int and String
  k.n[String]
     ^
Since

2.8.1

класс showAsInfix extends Annotation with StaticAnnotation

Эта аннотация настраивает вывод Scala для двухпараметрических обобщенных типов.

По умолчанию типы со символическими именами выводятся инфиксным способом, а типы без них выводятся с использованием обычного синтаксиса обобщенных типов.

Пример использования:

scala> class Map[T, U]
defined class Map

scala> def foo: Int Map Int = ???
foo: Map[Int,Int]

scala> @showAsInfix class Map[T, U]
defined class Map

scala> def foo: Int Map Int = ???
foo: Int Map Int
Аннотации
@deprecatedInheritance("Планируется окончательный статус в 2.14", "2.13.0")
Since

2.12.2

класс strictfp extends Annotation with StaticAnnotation

Если эта аннотация присутствует в методе или его содержащем классе, будет выведен флаг strictfp.

Аннотации
@deprecatedInheritance("Планируется окончательный статус в 2.14", "2.13.0")
Since

2.9

final класс switch extends Annotation with StaticAnnotation

Аннотация, применяемая к выражению match. Если она присутствует, компилятор проверит, что match скомпилирован в tableswitch или lookupswitch, и выведет ошибку, если он скомпилирован в серию условных выражений. Пример использования:

val Constant = 'Q'
def tokenMe(ch: Char) = (ch: @switch) match {
  case ' ' | '\t' | '\n'  => 1
  case 'A' | 'Z' | '$'    => 2
  case '5' | Constant     => 3  // a non-literal may prevent switch generation: this would not compile
  case _                  => 4
}

Примечание: для совпадений шаблонов с одним или двумя случаями компилятор генерирует инструкции перехода. Применение аннотации @switch к такому match не приводит к предупреждению.

Since

2.8

final класс tailrec extends Annotation with StaticAnnotation

Аннотация для метода, которая проверяет, будет ли метод скомпилирован с оптимизацией хвостовой рекурсии.

Если она присутствует, компилятор выведет ошибку, если метод не может быть оптимизирован в цикл.

Since

2.8

класс unspecialized extends Annotation with StaticAnnotation

Аннотация для метода, которая подавляет создание дополнительных специализированных форм на основе вложенных специализированных параметров типа.

Аннотации
@deprecatedInheritance("Планируется окончательный статус в 2.14", "2.13.0")
Since

2.10

класс unused extends Annotation with StaticAnnotation

Пометить элемент как неиспользуемый в данном контексте.

Предупреждения о неиспользовании подавляются для известных неиспользуемых элементов.

Например, параметр метода может быть помечен @unused потому, что метод предназначен для переопределения реализацией, которая использует этот параметр.

Аннотации
@getter() @setter()

final класс varargs extends Annotation with StaticAnnotation

Аннотация для метода, которая инструктирует компилятор генерировать метод-обёртку для Java varargs для взаимодействия. Эта аннотация может быть применена только к методам с повторяющимися параметрами.

Since

2.9

Члены-значения

объект elidable

Этот, на первый взгляд, бесполезный код был необходим, чтобы позволить людям использовать именованные константы для аннотации elidable. Это необходимо, чтобы убедить компилятор сложить константы: в противном случае, когда пришло время проверить уровень элизии, он видит дерево,

(Select(Level, Select(FINEST, Apply(intValue, Nil))))

вместо числа 300.

Since

2.8

© 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/annotation/index.html

Spec-Zone.ru

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