Scala(十一)注解与针对Java特性的注解

  1. Scala中的注解定义:注解就是插入代码中的标识,在scala编译器编译的时候可以对他们进行特殊的处理标识
  2. scala注解可以修饰什么:scala中可以为目标同时添加多个注解

    1. Class(类)

      @Entity 
      class Credentials
      // 给构造器添加注解,需要将注解放置在构造器之前,并加上一对圆括号(注解不带参数的话)
      class Credentials @Inject() (var username: String, var password: String)
    2. Method(方法)

      @Test 
      def testSomeFeature() {}
    3. Field(字段)

      //同时添加多个注解
      @BeanProperty 
      @Id 
      var username = _
    4. Paramter(参数)

      // 为类型参数添加注解
      class MyContainer[@specialized T]
  3. Scala自定义注解:自定义注解需要从注解特质中继承,Scala中提供了两类注解特质,这两类都继承了annotation.Annotation

    1. scala.annotation.ClassfileAnnotation 由Java编译器生成注解,继承自该类,如果注解需要传入参数的时候必须以具体参数名=参数值来传入参数
    2. scala.annotation.StaticAnnotation 由Scala编译器生成注解,如果继承该类,传入参数无限制

      object AnnotationLearn {
        def main(args: Array[String]): Unit = {
      
          val ty: Type = typeOf[Test]
          val symbol = ty.typeSymbol
          val annotation = symbol.annotations
          for (elem <- annotation) {
            val tree = elem.tree
            println(showRaw(tree))
          }
      
        }
      }
      //继承自该类的注解传入参数必须是具名参数,例如:@myAnnotation(name = "ClassfileAnnotation") 否则报错
      class myAnnotation(name: String) extends ClassfileAnnotation
      
      //继承自该注解无限制
      class myAnnotation1(name: String) extends StaticAnnotation
      
      @myAnnotation(name = "ClassfileAnnotation")
      @myAnnotation1("StaticAnnotation")
      class Test
  4. 针对Java特性的注解:对于那些不是很常用的Java特性,Scala使用注解,而不是修饰符关键字

    1. @SerialVersionUID:对于可序列化的类,你可以用@SerialVersionUID注解来指定序列化版本

      @SerialVersionUID(6157032470129070425L)
      class Employee extends Person with Serializable
    2. @throws:和Scala不同,Java编译器会跟踪受检异常。如果你从Java代码中调用Scala的方法,其签名应包含那些可能被抛出的受检异常。用@throws注解来生成正确的签名。

      class Book {
        @throws (classOf[IOException]) def read(filename: String) { ... }
        // Java版本为
        // void read(String filename) throws IOException
        ...
      }
      
      // 如果没有@throws注解,Java代码将不能捕获该异常
      try {
        book.read("war-and-peace.txt");
      } catch (IOException ex) {
        ...
      }
    3. @varargs:边长参数,可以从Java调用Scala的带有变长参数的方法。

      // 默认情况
      def process(agrs: String*)
      // Scala编译器会把变长参数翻译成序列:
      def process(args: Seq[String])   // 这样的方法签名在Java中使用很费劲
      
      // 加上 @varargs
      @varargs def process(args: String*)
      // 编译器将生成如下java方法
      void process(String... args)
    4. @BeanProperty:生成JavaBean风格的getter和setter方法。

    5. @volatile:它可以保证,一个线程在共享区中获取一个变量的值的副本时,都会强制刷新这个变量的值,保证自己获取到的这个变量的副本值时最新的

    @volatile var name="jack"
    //轻量级的java多线程的并发控制器
    1. @transient:默认会讲一个对象中的所有字段的值,都序列化到磁盘文件中去,加了@transient的字段,是瞬态的,序列化的时候会忽略这个值,反序列化这个值就没有了

      @transient var name="leo"
      //瞬间字段,不会序列化这个字段
    2. @BooleanBeanProperty:生成is风格的getter方法

    3. @deprecated:标记过期方法
    4. @unchecked:让编译器发出类型转换的警告
    5. @implicitNotFound:注解用于某个隐士参数不存在的时候生成有意义的错误提示。

      @deprecated(message = "Use factorial(n: BigInt) instead")
      def factorial(n: Int): Int = ...
    6. @deprecated:如果给特性加上@deprecated注解,则每当编译器遇到这个特性的使用时都会生成一个警告信息。
    7. @specialized:让编译器自动对基本类型进行打包解包,在泛型中还可以指定输入类型的子集

      def allDifferent[@specialized T](x: T, y: T, z: T) = ...
              // 你也可以将特化限定在某几个可选类型的子集
      def allDifferent[@specialized(Long, Double) T](x: T, y: T, z: T) = ...
    8. @switch:在C++Java中,switch语句通常被编译成跳转表,用于多种情况的判断,比if/else方便高效。Scala也会尝试对匹配语句生成跳转表,使用@switch注解。另一个常见的优化方法是使用@inline来进行内联:用函数体替换函数调用,这与C++Javainline函数相同。 而@noinline来告诉编译器不要内联。

      (n @switch) match {
        case 0 => "Zero"
        case 1 => "One"
        case _ => "?"
      }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值