注解
一、注解简介
注解都是 @ 符号开头的,是一种补充信息,本质上都一种数据类型,是一种接口类型。
到 Java 8 为止 Java SE 提供了 11 个内置注解。其中有 5 个是基本注解,它们来自于 java.lang 包。有 6 个是元注解(注解内的注解),它们来自于 java.lang.annotation 包,自定义注解会用到元注解。
注解常见的作用有以下几种:
1、生成帮助文档。这是最常见的,也是 Java 最早提供的注解。常用的有 @see、@param 和 @return 等;
2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是 Spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量;
3、在编译时进行格式检查。如把 @Override 注解放在方法前,如果这个方法并不是重写了父类方法,则编译时就能检查出。
三、@Deprecated注解
Java 中 @Deprecated 可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
四、@SuppressWarnings:抑制编译器警告
@SuppressWarnings 注解主要用在取消一些编译器产生的警告对代码左侧行列的遮挡,有时候这样会挡住我们断点调试时打的断点。
注解的使用有以下三种:
抑制单类型的警告:@SuppressWarnings(“unchecked”)
抑制多类型的警告:@SuppressWarnings(“unchecked”,“rawtypes”)
抑制所有类型的警告:@SuppressWarnings(“unchecked”)
关键字 | 用途 |
---|---|
all | 抑制所有警告 |
boxing | 抑制装箱、拆箱操作时候的警告 |
cast | 抑制映射相关的警告 |
dep-ann | 抑制启用注释的警告 |
deprecation | 抑制过期方法警告 |
fallthrough | 抑制在 switch 中缺失 breaks 的警告 |
finally | 抑制 finally 模块没有返回的警告 |
hiding | 抑制相对于隐藏变量的局部变量的警告 |
incomplete-switch | 忽略不完整的 switch 语句 |
nls | 忽略非 nls 格式的字符 |
null | 忽略对 null 的操作 |
rawtypes | 使用 generics 时忽略没有指定相应的类型 |
restriction | 抑制禁止使用劝阻或禁止引用的警告 |
serial | 忽略在 serializable 类中没有声明 serialVersionUID 变量 |
static-access | 抑制不正确的静态访问方式警告 |
synthetic-access | 抑制子类没有按最优方法访问内部类的警告 |
unchecked | 抑制没有进行类型检查操作的警告 |
unqualified-field-access | 抑制没有权限访问的域的警告 |
unused | 抑制没被使用过的代码的警告 |
五、@SafeVarargs注解
可用 @SafeVarargs 注解抑制编译器警告
注意:@SafeVarargs注解不适用于非 static 或非 final 声明的方法,对于未声明为 static 或 final 的方法,如果要抑制 unchecked 警告,可以使用 @SuppressWarnings 注解。
六、@FunctionalInterface注解
在学习 Lambda 表达式时,我们提到如果接口中只有一个抽象方法(可以包含多个默认方法或多个 static 方法),那么该接口就是函数式接口。
@FunctionalInterface 就是用来指定某个接口必须是函数式接口,所以
@FunInterface 只能修饰接口,不能修饰其它程序元素。
注意:接口只能有一个方法;“@FunctionInterface”批注无效;FunInterface不是functional接口
七、Java 元注解作用及使用
元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解。
@Documented、@Target、@Retention 和 @Inherited。Java 8 又增加了 @Repeatable 和 @Native 两个注解。
1、@Documented
@Documented 是一个标记注解,没有成员变量。用 @Documented 注解修饰的注解类会被 JavaDoc 工具提取成文档。
2、@Target
@Target 注解用来指定一个注解的使用范围,即被 @Target 修饰的注解可以用在什么地方。@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组,下表为 ElementType 常用的枚举常量。
(在注解中抽象方法称为属性)
3、@Retention
@Retention 用于描述注解的生命周期,也就是该注解被保留的时间长短。@Retention 注解中的成员变量(value)用来设置保留策略,value 是 java.lang.annotation.RetentionPolicy 枚举类型,RetentionPolicy 有 3 个枚举常量,如下所示。
SOURCE:在源文件中有效(即源文件保留)
CLASS:在 class 文件中有效(即 class 保留)
RUNTIME:在运行时有效(即运行时保留)
生命周期大小排序为 SOURCE < CLASS < RUNTIME
4、@Repeatable
@Repeatable 注解是 Java 8 新增加的,它允许在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助 @Repeatable 注解。
八、Java 自定义注解
如果在注解里定义了成员变量,那么使用该注解时就应该为它的成员变量指定值;注解中的成员变量也可以有默认值,可使用 default 关键字。
当为注解的成员变量指定了默认值,那么使用该注解时就可以不为这些成员变量赋值,而是直接使用默认值。
当然也可以在使用 MyTag 注解时为成员变量指定值,如果为 MyTag 的成员变量指定了值,则默认值不会起作用。
根据注解是否包含成员变量,可以分为如下两类。
- 标记注解:没有定义成员变量的注解类型被称为标记注解。这种注解仅利用自身的存在与否来提供信息,如前面介绍的 @Override、@Test 等都是标记注解。
- 元数据注解:包含成员变量的注解,因为它们可以接受更多的元数据,所以也被称为元数据注解。
@Target 注解用来指定一个注解的使用范围;@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组,下表为 ElementType 常用的枚举常量。
名称 | 说明 |
---|---|
CONSTRUCTOR | 用于构造方法 |
FIELD | 用于成员变量(包括枚举常量) |
LOCAL_VARIABLE | 用于局部变量 |
METHOD | 用于方法 |
PACKAGE | 用于包 |
PARAMETER | 用于类型参数(JDK 1.8新增) |
TYPE | 用于类、接口(包括注解类型)或 enum 声明 |
**注意:**当用户自定义注解只有一个属性时通常将名字设置为value
Java 数据结构
Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:
- 枚举(Enumeration)
- 位集合(BitSet)
- 向量(Vector)
- 栈(Stack)
- 字典(Dictionary)
- 哈希表(Hashtable)
- 属性(Properties)
三、向量(Vector)
向量(Vector)类和传统数组非常相似,但是Vector的大小能根据需要动态的变化。
在创建对象的时候不必给对象指定大小,它的大小会根据需要动态的变化。
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:
1、Vector 是同步访问的。
2、Vector 包含了许多传统的方法,这些方法不属于集合框架。
第一种构造方法创建一个默认的向量,默认大小为 10:Vector()
第二种构造方法创建指定大小的向量:Vector(int size)
第三种构造方法创建指定大小的向量,并且增量用 incr 指定。增量表示向量每次增加的元素数目:Vector(int size,int incr)
第四种构造方法创建一个包含集合 c 元素的向量:Vector(Collection c)
四、栈(Stack)
栈(Stack)实现了一个后进先出(LIFO)的数据结构。
栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。
如下:
方法 | 方法描述 |
---|---|
boolean empty() | 测试堆栈是否为空。 |
Object peek( ) | 查看堆栈顶部的对象,但不从堆栈中移除它。 |
Object pop( ) | 移除堆栈顶部的对象,并作为此函数的值返回该对象。 |
Object push(Object element) 把 | 项压入堆栈顶部。 |
int search(Object element) | 返回对象在堆栈中的位置,以 1 为基数。 |
五、哈希表(Hashtable)
Hashtable类提供了一种在用户定义键结构的基础上来组织数据的手段。
Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。然而,Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。
Hashtable定义了四个构造方法。第一个是默认构造方法:
Hashtable()
第二个构造函数创建指定大小的哈希表:
Hashtable(int size)
第三个构造方法创建了一个指定大小的哈希表,并且通过fillRatio指定填充比例。填充比例必须介于0.0和1.0之间,它决定了哈希表在重新调整大小之前的充满程度:
Hashtable(int size,float fillRatio)
第四个构造方法创建了一个以M中元素为初始化元素的哈希表。哈希表的容量被设置为M的两倍。
Hashtable(Map m)
Hashtable中除了从Map接口中定义的方法外,还定义了以下方法:
方法 | 方法描述 |
---|---|
void clear( ) | 将此哈希表清空,使其不包含任何键。 |
Object clone( ) | 创建此哈希表的浅表副本。 |
boolean contains(Object value) | 测试此映射表中是否存在与指定值关联的键。 |
boolean containsKey(Object key) | 测试指定对象是否为此哈希表中的键。 |
boolean containsValue(Object value) | 如果此 Hashtable 将一个或多个键映射到此值,则返回 true。 |
Enumeration elements( ) | 返回此哈希表中的值的枚举。 |
Object get(Object key) | 返回指定键所映射到的值,如果此映射不包含此键的映射,则返回 null. 更确切地讲,如果此映射包含满足 (key.equals(k)) 的从键 k 到值 v 的映射,则此方法返回 v;否则,返回 null。 |
boolean isEmpty( ) | 测试此哈希表是否没有键映射到值。 |
Enumeration keys( ) | 返回此哈希表中的键的枚举。 |
Object put(Object key, Object value) | 将指定 key 映射到此哈希表中的指定 value。 |
void rehash( ) | 增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。 |
Object remove(Object key) | 从哈希表中移除该键及其相应的值。 |
int size( ) | 返回此哈希表中的键的数量。 |
String toString( ) | 返回此 Hashtable 对象的字符串表示形式,其形式为 ASCII 字符 ", " (逗号加空格)分隔开的、括在括号中的一组条目。 |
六、属性(Properties)
Properties 继承于 Hashtable.Properties 类表示了一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。Properties 类被许多Java类使用。例如,在获取环境变量时它就作为System.getProperties()方法的返回值。
Properties 定义如下实例变量.这个变量持有一个 Properties 对象相关的默认属性列表。
Properties defaults;
Properties类定义了两个构造方法. 第一个构造方法没有默认值。
Properties()
第二个构造方法使用propDefault 作为默认值。两种情况下,属性列表都为空:
Properties(Properties propDefault)
除了从 Hashtable 中所定义的方法,Properties 还定义了以下方法:
方法 | 方法描述 |
---|---|
String getProperty(String key) | 用指定的键在此属性列表中搜索属性。 |
String getProperty(String key, String defaultProperty) | 用指定的键在属性列表中搜索属性。 |
void list(PrintStream streamOut) | 将属性列表输出到指定的输出流。 |
void list(PrintWriter streamOut) | 将属性列表输出到指定的输出流。 |
void load(InputStream streamIn) throws IOException | 从输入流中读取属性列表(键和元素对)。 |
Enumeration propertyNames( ) | 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 |
Object setProperty(String key, String value) | 调用 Hashtable 的方法 put。 |
void store(OutputStream streamOut, String description) | 以适合使用 load(InputStream)方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 |
七、队列(Queue)
Queue的实现类有LinkedList和PriorityQueue。最常用的实现类是LinkedList。
Queue的6个方法分类:
压入元素(添加):add()、offer()
相同:未超出容量,从队尾压入元素,返回压入的那个元素。
区别:在超出容量时,add()方法会对抛出异常,offer()返回false
弹出元素(删除):remove()、poll()
相同:容量大于0的时候,删除并返回队头被删除的那个元素。
区别:在容量为0的时候,remove()会抛出异常,poll()返回false
获取队头元素(不删除):element()、peek()
相同:容量大于0的时候,都返回队头元素。但是不删除。
区别:容量为0的时候,element()会抛出异常,peek()返回null。
抛出异常 | 返回特殊值 | |
---|---|---|
插入 | add(e) | offer(e) |
删除 | remove() | poll() |
检查 | element() | peek() |
注意:remove() 和 poll() 方法可移除和返回队列的头。
element() 和 peek() 返回但不移除队列的头。
(将文件刷新属于“持久化操作”是将数据保留到磁盘)