Chapter10 注 解

Chapter10這節還是挺重要的,在看Spark源碼的過程中,發現其源碼使用到很多註解的知識,所以這節一定要好好學習。


1. 什麼是註解

  • 註解:是那些你插入到代碼中以方便工具可以對它們進行處理的標籤

  • 註解作用:是描述那些被註解的表達式、變量、字段、方法或類型。

  • Java中註解不會影響編譯器生成字節碼,而Scala中會影響。

  • 下面是註解的一個簡單實例:

    import scala.reflect.BeanProperty
    import javax.persistence.Entity
    import javax.persistence.Id
    import org.junit._
    import org.junit.Assert._

    @Entity class Credentials {
      @Id @BeanProperty var username : String = _
      @BeanProperty var password : String = _
    }

    class MyTest {
      @Test(timeout = 100) def testSomeFeature() {
        assertTrue(6 * 7 == 42)
      }
    }

@Entity註解標識該類是一個實體,@id是設置主鍵,@BeanProperty在Chapter05中講過,它會生成getter和setter兩種方法,@Test表示測試方法,在這裏可以測試期望異常和超時時間。具體含義可以上google查詢Junit和JPA註解


2. 什麼可以被註解

  • 類、方法、字段、局部變量和參數都可添加註解。

  • 可以添加多個註解,沒有先後順序。

     @BeanProperty @Id  var lastName = ""
    
  • 主構造函數添加註解時,註解放置在構造器之前,並加上一對圓括號

    class Credentials @Inject() (var username: String, var password: String) { 
    }
    
  • 表達式添加註解,需要在表達式後添加冒號,然後是註解。

    (n: @unchecked) match { ... }
    

3. 註解參數

  • 註解可以帶參數。

    @Test(timeout = 100, expected = classOf[IOException]) 
    def testNonexistentFile() {     
        new FileReader("/fred.txt")
      }
    
  • 註解不帶參數圓括號可以省略。註解有默認值,比如Test的Timeout的默認值爲0,表示沒有超時,expected默認是不預期任何異常。


4. 針對Java特性的註解

  • @volatile將字段標記爲易失的,易失的字段可以被多個線程同時更新。

  • @transient將字段標記爲瞬態的,瞬態的字段不會被序列化,只會作爲臨時的緩存數據。(序列化:將對象狀態信息轉換爲可以存儲或傳輸的形式的過程)

  • @strictfp使用IEEE的double進行浮點計算,而不是使用80位擴展精度,計算慢但移植性高。

  • @native標記在C或C++代碼中的實現方法。


5. 標記接口

  • @cloneable@remote標記接口可被克隆或遠程的對象。

  • @SerialVersionUID指定序列化版本,標記可序列化的類。

    @cloneable @remote @SerialVersionUID(6157032470129070425L)
    class Employee(var name: String, var salary: Double) extends Serializable {
      var hireDay = new Date
    }

6. 受檢異常和變長參數

  • @throws標記可能拋出異常的對象。

  • @varargs可以讓你從Java調用Scala的帶有變長參數的方法。

    class Processor {
      @varargs def process(args: String*) {
        println(args.mkString("<", "|", ">"))
      }
    }

7. 跳轉表生成與內聯

  • C++和Java中switch通常被編譯爲跳轉表,更高效,@switch檢查Scala是不是將match編譯成跳轉表。
    (n: @switch) match {
      case 0 => "Zero"
      case 1 => "One"
      case _ => "?"
    }
  • @inline將方法標記爲內聯方法,@noinline告訴編譯器不要內聯。

8. 可省略方法

  • @elidable給生產代碼中需要移除的方法打上標記。它後面會接一個參數,

     @elidable(800) def dump(props: Map[String, String]) {}
    
  • 編譯時需要使用下面命令:

    scalac -Xelide-below 800 prog.scala
    
  • 具體參數表如下,默認值低於1000的方法都會被省略。
    這裏寫圖片描述


9. 基本類型的特殊化

  • 給類型參數添加@specialized註解,編譯器會自動生成對應類型的所有方法。不需要自己寫重載函數。

  • 可用的類型有:Unit、Boolean、Byte、Short、Char、Int、Long、Float、Double

    def allDifferent[@specialized(Double, Long) T](x: T, y: T, z: T) = x != y && x != z && y != z
    

10. 用於錯誤和警告的註解

  • @deprecated註解被添加後,編譯器遇到被註解的方法使用時就會生成一個警告,它有兩個參數可選,messsage和since。

    @deprecated(message = "Use factorial(n: BigInt) instead")
    def factorial(n: Int): Int = if (n <= 0) 1 else n * factorial(n - 1)
    
  • @implicitNotFound註解用於某個隱式參數不存在時會生成有意義的錯誤提示。

  • @unchecked註解用於在匹配不完整時取消警告信息。


【待續】

發佈了84 篇原創文章 · 獲贊 324 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章