zoukankan      html  css  js  c++  java
  • Scala入门到精通——第十六节 泛型与注解

    本节主要内容

    1. 泛型(Generic Type)简单介绍
    2. 注解(Annotation)简单介绍
    3. 注解经常使用场景

    1. 泛型(Generic Type)简单介绍

    泛型用于指定方法或类能够接受随意类型參数,參数在实际使用时才被确定,泛型能够有效地增强程序的适用性,使用泛型能够使得类或方法具有更强的通用性。泛型的典型应用场景是集合及集合中的方法參数,能够说同java一样,scala中泛型无处不在,详细能够查看scala的api

    1 泛型类

    //单个泛型參数的使用情况
    class Person[T](var name:T)
    
    class Student[T](name:T) extends Person(name)
    
    object GenericDemo {
      def main(args: Array[String]): Unit = {
        println(new Student[String]("摇摆少年梦").name)
      }
    }

    多个泛型參数的使用情况:

    class Person[T](var name:T)
    
    class Student[T,S](name:T,var age:S) extends Person(name)
    
    object GenericDemo {
      def main(args: Array[String]): Unit = {
        println(new Student[String,Int]("摇摆少年梦",18).name)
      }
    }
    D:ScalaWorkspaceScalaChapter16incnscalaxtwy>javap -private Person.class
    Compiled from "GenericDemo.scala"
    public class cn.scala.xtwy.Person<T> {
      private T name;
      public T name();
      public void name_$eq(T);
      public cn.scala.xtwy.Person(T);
    }
    
    D:ScalaWorkspaceScalaChapter16incnscalaxtwy>javap -private Student.class
    Compiled from "GenericDemo.scala"
    public class cn.scala.xtwy.Student<T, S> extends cn.scala.xtwy.Person<T> {
      private S age;
      public S age();
      public void age_$eq(S);
      public cn.scala.xtwy.Student(T, S);
    }

    从上面的代码不难看出,scala泛型对应于java中的泛型,掌握了java中的泛型也就掌握了scala中的泛型

    2. 注解(Annotation)简单介绍

    Annotation是一种对程序代码进行描写叙述的结构化信息。

    Annotation能够分布在程序的不论什么地方,能够注解变量、类、方法、參数等多种元素,它的主要功能有以下几种:
    1 自己主动生成scala文档

    scala.collection.immutable.HashMap类对应部分源代码:

    /** This class implements immutable maps using a hash trie.
     *
     *  '''Note:''' The builder of this hash map may return specialized representations for small maps.
     *
     *  @tparam A      the type of the keys contained in this hash map.
     *  @tparam B      the type of the values associated with the keys.
     *
     *  @author  Martin Odersky
     *  @author  Tiark Rompf
     *  @version 2.8
     *  @since   2.3
     *  @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#hash_tries "Scala's Collection Library overview"]]
     *  section on `Hash Tries` for more information.
     *  @define Coll `immutable.HashMap`
     *  @define coll immutable hash map
     *  @define mayNotTerminateInf
     *  @define willNotTerminateInf
     */
    @SerialVersionUID(2L)
    class HashMap[A, +B] extends AbstractMap[A, B]
                            with Map[A, B]
                            with MapLike[A, B, HashMap[A, B]]
                            with Serializable
                            with CustomParallelizable[(A, B), ParHashMap[A, B]]
    {

    上述annotation生成的文档内容例如以下:
    这里写图片描写叙述

    2 检查程序中可能出现的语法问题

    //当程序使用该API时,给出对应提示,属于语法检查范畴
     @deprecated("Use the `merged` method instead.", "2.10.0")
      def merge[B1 >: B](that: HashMap[A, B1], mergef: MergeFunction[A, B1] = null): HashMap[A, B1] = merge0(that, 0, liftMerger(mergef))
    

    3 规定程序行为

    //@BeanProperty。要求程序生成对应getter,setter方法。与java命名规范一致
    class Student[T,S](name:T,var age:S) extends Person(name)
    {
      @BeanProperty var studentNo:String=null
    }
    

    当然。annotation还有其他功能,上面三种仅仅是平时在编敲代码时最为经常使用的功能

    annotation具有例如以下语法格式:

    class A
    class B extends A{
      //同java一样。採用@+注解关键字对方法、变量
      //类等进行注解标识
      //以下的注解用于标识getName方法在未来会被丢弃
      //不推荐使用
      @deprecated def getName()="Class B"
    }
    
    object AnnotationDemo{
      def main(args: Array[String]): Unit = {
        var b=new B()
        //在调用的时候。编译器出给出对应提示
        b.getName()
      }
    }

    3. 注解经常使用场景

    注解的经常使用场景包含volatile。transient。native,SerialVersionUID,serializable5个。用于对变量或方法进行注解,当中volatile用于标识变量可能会被多个线程同一时候改动,它不是线程安全的;transient用于标识变量是瞬时的,它不会被持久化;native用于标识算法来自C或C++代码实现

    
    
    abstract class A
    { 
      //native用于标记 cplusplusMethod为c或c++中实现的本地方法
      @native def cplusplusMethod()
    }
    
    //标记B可被序列化
    //注解声明序列化版本号
    @SerialVersionUID(1000330L)
    @serializable
    class B extends A{
      //volatile注解标记变量name非线程安全
      @volatile var name:String="B"
      //transient注解用于标记变量age不被序列化
      @transient var age:Int=40
    
    }
    

    以下举下对象序列化的样例:

    //以下的代码编译时不会出问题,但运行时会抛出异常
    class Person{
      var name:String="zzh"
      var age:Int=0
      override def toString()="name="+name+" age="+age
    }
    
    object Serialize {
      def main(args: Array[String]): Unit = {
         val file = new File("person.out")
    
            val oout = new ObjectOutputStream(new FileOutputStream(file)) 
            val person = new Person 
            oout.writeObject(person)  
            oout.close()
    
            val oin = new ObjectInputStream(new FileInputStream(file)) 
            val newPerson = oin.readObject()
            oin.close();  
            println(newPerson)
      }
    }
    
    Exception in thread "main" java.io.NotSerializableException: cn.scala.xtwy.serialize.Person
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at cn.scala.xtwy.serialize.Serialize$.main(Serialize.scala:22)
        at cn.scala.xtwy.serialize.Serialize.main(Serialize.scala)
    

    此时在Person类前加@serializable则能够对对象进行正常序列化

    //声明对象可序列化
    @serializable
    class Person{
      var name:String="zzh"
      var age:Int=0
      override def toString()="name="+name+" age="+age
    }
    
    object Serialize {
      def main(args: Array[String]): Unit = {
         val file = new File("person.out")
    
            val oout = new ObjectOutputStream(new FileOutputStream(file)) 
            val person = new Person 
            oout.writeObject(person)  
            oout.close()
    
            val oin = new ObjectInputStream(new FileInputStream(file)) 
            val newPerson = oin.readObject()
            oin.close();  
            println(newPerson)
      }
    }
    //反序列化后的输出结果为:
    //name=zzh age=0

    假设给成员变量加@transient注解的话。则对应的成员变量不会被序列化。此时假设进行反序列化的话,对应成员变量为null,如:

    package cn.scala.xtwy.serialize
    
    import java.io.File
    import java.io.ObjectOutputStream
    import java.io.FileOutputStream
    import java.io.ObjectInputStream
    import java.io.FileInputStream
    
    @serializable
    class Person{
      //@transient注解声明后。成员变量不会被充列化
      @transient var name:String="zzh"
      var age:Int=0
      override def toString()="name="+name+" age="+age
    }
    
    object Serialize {
      def main(args: Array[String]): Unit = {
         val file = new File("person.out")
    
            val oout = new ObjectOutputStream(new FileOutputStream(file)) 
            val person = new Person 
            oout.writeObject(person)  
            oout.close()
    
            val oin = new ObjectInputStream(new FileInputStream(file)) 
            val newPerson = oin.readObject()
            oin.close();  
            println(newPerson)
      }
    }
    //反序列化后的输出
    //name=null age=0

    加入公众微信号,能够了解很多其他最新Spark、Scala相关技术资讯
    这里写图片描写叙述

  • 相关阅读:
    (转载)SPSS之判别分析——决策树——以iris.sav为例
    (转载)SPSS之判别分析——以iris.sav为例
    python实现GA求二元函数最大值(来自知乎)
    (转载)Python在数学建模中的简单应用
    (转载)Python3 列表,数组,矩阵的相互转换
    【翻译自mos文章】在RHEL7/OL7上安装Oracle 12.1.0.2的server端或者client时,报须要&quot;compat-libstdc++&quot;包
    Material Design Support 8大控件介绍
    关于程序猿的技术发展讨论
    《C程序猿从校园到职场》带领大家从校园走向职场
    IE8下submit表单没反应
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6816402.html
Copyright © 2011-2022 走看看