Scala学习笔记 A2/L1篇 - 注解 Annotation
教材:快学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
可被克隆的对象 对应JavaClonable
标记接口
@remote
远程对象 对应Javajava.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
@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,有message
和since
参数
@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 = 2
draw(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
取消与型变相关的错误提示