Scala学习笔记|Scala学习笔记 A2/L1篇 - 注解 Annotations

教材:快学Scala
chapter 15. 注解 Annotations

  • 注解用于被编译器或外部工具处理
  • @deprecated注解用于标记已过时的特性
15.1 什么是注解
  • 插入到代码中以便有工具可以对它们进行处理的标签
  • Java注解不影响编译器将源码翻译成字节码的过程;Scala的注解可以影响编译过程
15.2 什么可以被注解
  • 几乎什么都可以被注解
    @Entity class Credentials // 类
    @Test def testSomeFeats() {} // 方法
    @BeanProperty var username = _ // 局部变量
    class Credentials @Inject() (var x: Int, ...) // 主构造器 @Inject()
    (maMap.get(key): @unchecked) match {...} // 表达式 :@unchecked
    class MyContainer[@specialized T] // 类型参数
    String @cps[Unit] // @cps[Unit] 针对实际类型的注解,这里是为String类型添加注解
  • 多个注解没有先后影响
  • 注解参数 @Test(timeout = 100, expected = classOf[IOException])
  • 注解实现,扩展Annotation特质 class unchecked extends annotation.Annotation
15.5 Annotations for Java Features
  • Java修饰符关键字 -> 注解
    @volatile 易失字段,可以被多个线程同时更新
    @transient 瞬态字段,不会被徐泪花,用于临时保存的数据或容易重新计算的数据
    @strictfp 使用IEEE的double值进行浮点运算
    @native 在C/C++代码中实现的方法
  • Java标记接口(Marker Interface) -> 注解
    @clonable 可被克隆的对象 对应Java Clonable 标记接口
    @remote 远程对象 对应Java java.rmi.Remote 标记接口
    @SerialVersionUID 指定序列化版本
  • Java受检异常(Checked Exceptions) -> 注解
    如果从Java代码中调用Scala方法,其签名应包含可能被抛出的受检异常
    @throws(classOf[IOException]) def ... 对应Java ... throws IOException
  • Java变长参数(Variable Arguments) -> 注解
    @varargs def process(args: String*) 对应Java变长参数 void process(String... args)
  • JavaBeans -> 注解
    @BeanProperty 生成JavaBean风格的getter和setter
15.6 Annotations for Optimizations
【Scala学习笔记|Scala学习笔记 A2/L1篇 - 注解 Annotations】@tailrec 显式提示编译器尾递归优化
尾递归,如果递归计算过程的最后一步是递归调用同一个方法,编译器会自动尾递归优化
消除递归的另一种方法:蹦床机制 TailCalls
@switch 检查match语句是否编译成了跳转表(类似C++的switch语句编译效果)
@inline 方法内联 @noinline 不要做内联
@elidable 给那些可以在生成代码中移除的方法打上标记
@elidable(500) def dump(props: Map[Int, Int]) {...}
如果编译命令为 scalac -Xelide-below 800 myprog.scala 则上述dump代码不会被生成
还可以用常量值代表,如INFO=800,WARNING=1000,ASSERTION=2000
assert方法是@elidable(ASSERTION) 忽略assert的编译命令为 -Xelide-below MAXIMUM 缺省情况下不禁用assert
@specialized(Long, Double) 将泛型代码转换为特定基本类型版本的代码
15.7 Annotations for Errors and Warnings
@deprecated 遇到这个特性的使用时会产生一个warning,有messagesince参数
@deprecatedName 参数注解,用于给出一个被遗弃的参数名称
def draw(@deprecatedName('sz) size: Int, style: Int = 0) {println("drawing shape size = " + size)) // draw: (size: Int, style: Int)Unit draw(1) // drawing shape size = 1 draw(size = 2) // drawing shape size = 2draw(sz = 3) // warning: there was one deprecation warning; re-run with -deprecation for details // drawing shape size = 3

单引号(')开头的名称是一个符号(symbol) 名称相同的符号一定是唯一的
符号比字符串效率高,符号的==方法判断引用是否相同,字符串的==方法需要比对内容
符号的语义:A symbol denotes a name of some item in a program.
@implicitNotFound 某个隐式参数不存在的时候生成有意义的错误提示
@unchecked 在match语句匹配不完整时取消警告信息
@uncheckedVariance 取消与型变相关的错误提示

    推荐阅读