Scala入门到精通——第十六节 泛型与注解
本节主要内容
- 泛型(Generic Type)简介
- 注解(Annotation)简介
- 注解常用场景
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:\ScalaWorkspace\ScalaChapter16\bin\cn\scala\xtwy>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:\ScalaWorkspace\ScalaChapter16\bin\cn\scala\xtwy>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 Serializablewith 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=0override 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.Personat 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)
- 1
此时在Person类前加@serializable则可以对对象进行正常序列化
//声明对象可序列化
@serializable
class Person{var name:String="zzh"var age:Int=0override 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.serializeimport 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=0override 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
Scala入门到精通——第十六节 泛型与注解相关推荐
- Scala入门到精通——第二十六节 Scala并发编程基础
本节主要内容 Scala并发编程简介 Scala Actor并发编程模型 react模型 Actor的几种状态 Actor深入使用解析 1. Scala并发编程简介 2003 年,Herb Sutte ...
- Scala入门到精通——第十四节 Case Class与模式匹配(一)
本节主要内容 模式匹配入门 Case Class简介 Case Class进阶 1. 模式匹配入门 在Java语言中存在switch语句,例如: //下面的代码演示了java中switch语句的使用 ...
- Scala入门到精通——第二十九节 Scala数据库编程
本节主要内容 Scala Mavenproject的创建 Scala JDBC方式訪问MySQL Slick简单介绍 Slick数据库编程实战 SQL与Slick相互转换 本课程在多数内容是在官方教程 ...
- Scala入门到精通——第二十五节 提取器(Extractor)
本节主要内容 apply与unapply方法 零变量或变量的模式匹配 提取器与序列模式 scala中的占位符使用总结 1. apply与unapply方法 apply方法我们已经非常熟悉了,它帮助我们 ...
- Scala入门到精通——第二十四节 高级类型 (三)
本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在Scala中,类(class)与类型(type)是两个不一样的概念. ...
- Scala入门到精通——第十九节 隐式转换与隐式参数(二)
本节主要内容 隐式参数中的隐式转换 函数中隐式参数使用概要 隐式转换问题梳理 1. 隐式参数中的隐式转换 前一讲中,我们提到函数中如果存在隐式参数,在使用该函数的时候如果不给定对应的参数,则编译器会自 ...
- Scala入门到精通——第十五节 Case Class与模式匹配(二)
本节主要内容 模式匹配的类型 for控制结构中的模式匹配 option类型模式匹配 1. 模式的类型 1 常量模式 object ConstantPattern{def main(args: Arra ...
- Scala入门到精通——第二十节 类型参数(二)
本节主要内容 Ordering与Ordered特质 上下文界定(Context Bound) 多重界定 类型约束 1. Ordering与Ordered特质 在介绍上下文界定之前,我们对Scala中的 ...
- Scala入门到精通——第十节 Scala类层次结构、Traits初步
本节主要内容 Scala类层次结构总览 Scala中原生类型的实现方式解析 Nothing.Null类型解析 Traits简介 Traits几种不同使用方式 1 Scala类层次结构 Scala中的类 ...
最新文章
- 阿里开源分布式限流框架 -Sentinel Go 0.3.0 发布,支持熔断降级能力
- 逆天Kali带你游遍大江南北~安全之前人铺路!
- Linux命令行中的特殊符号_特殊字符
- 传统POS/终端/银联POS简介
- 网站漏洞扫描工具_如何实现免费网站漏洞扫描?推荐一款神器给你
- java 高性能代码_[Java教程]Javascript高性能代码(一)
- Camshift算法原理及其Opencv实现
- tensorflow之reshape
- 关于es6中新增的一些方法----数组篇
- npm install 报错 @1.0.0 dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf..
- 支付宝扫码转账到银行卡/飞行模式
- dcos里面跑jenkins的问题
- git pull 出现 from the remote, but no such ref was fetched 已解决
- 数学建模算法学习笔记
- 小型机和服务器有何区别
- 财务复式记账和平行登记有什么区别
- 放个N老的程序,留着以后看
- 安卓逆向小案例——某新闻APP请求头urlSign还原
- 计算涨价百分比php,价格上涨率计算公式,涨跌百分比计算公式
- HCNP——水平分割、毒性逆转、触发更新、毒性路由
热门文章
- 1027 打印沙漏 (20分)——27行代码AC(结构清晰)
- (解题报告)L1-032 Left-pad (20分)——15行代码AC
- 两个有序链表序列的交集 (20分)(最佳解法)
- pcb设计实战与应用智能手机_机构强烈推荐+突破临界点+全球第一大PCB厂商=鹏鼎控股...
- oracle ora01732,一天一小步_2008.5.02: ora-01732错误
- 华为k662c的虚拟服务器,华为k662c路由器怎么设置
- vue mianjs 引用css_vue 学习记录八——webpack中常见的配置项
- maven 排除pom依赖_Maven依赖排除 禁止依赖传递 取消依赖的方法
- setfacl 权限导出_Linux如何使用setfacl命令创建权限文件
- php链接mysql验证用户登录,PHP连接mysql验证用户名是否存在