一、枚举
package com.alice.innerclass_.innerclass02;
// 如果希望在以后在这个地方生成自己的一些信息
/*
比如这个代码的作者是谁
这个代码的版本是谁
可以在设置中的Editor中的File and Code Templates的Includes的File Header中修改
将自己的版权,以及一些信息写上去
*/
public class EnumAndAnnotation01 {
public static void main(String[] args) {
// 使用
Season spring = new Season("春天", "温暖");
Season winter = new Season("冬天", "寒冷");
Season summer = new Season("夏天", "炎热");
Season autumn = new Season("秋天", "凉爽");
// 假如现在又乱增加了一个季节,对于季节而言,值或者对象是固定的
// 不会有更多的季节,因为它可以随便增加,破坏了这个类设计的初衷
// 这种设计不能体现季节是固定的四个对象,因此这样的设计不合理
// 我们希望这个类就是四个对象,自己创建好
// 并且当前还能够通过set方法随便更改
// 所以传统的方式写不合适。
// 因此需要引入枚举类,即把具体的对象一个个的列举出来的类,就称为
// 枚举类
// 总结:
// 创建Season对象有如下的几个特点
// 1、季节的值是有限的几个值(spring,summer,autumn,winter)
// 2、只读,不需要修改
/*
解决方案:枚举
*/
Season other = new Season("xxx", "yyy");
}
}
class Season { // 类
private String name;
private String desc; // 描述
// 构造器
public Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
// get set
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
/*
进入第十一章-枚举和注解
在枚举和注解这章要讲解:
自定义类实现枚举
enum关键字实现枚举
JDK内置的基本注解类型
@override
@deprecated
@suppresswarnings
元注解:对注解进行注解
一、由一个需求引出枚举类型
要创建季节Season对象,请设计并完成。
Enumeration
*/
// 02
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class Enum02 {
public static void main(String[] args) {
// 第一步将构造器私有,防止new
// 第二步去掉set相关的方法,防止属性被修改
// 第三步在类内部创建固定的对象
// 第四步使用,
System.out.println(SeasonCopy.AUTUMN);
System.out.println(SeasonCopy.SPRING);
System.out.println(SeasonCopy.SUMMER);
System.out.println(SeasonCopy.WINTER);
/*
总结:
1、不需要提供set方法,因为枚举对象值通常是只读
2、对枚举对象/属性进行使用,使用final+static共同修饰,实现底层的优化
3、枚举对象名通常需要使用全部大写,常量的命名规范
4、枚举对象根据需要,也可以有多个属性
*/
}
}
class SeasonCopy { // 类
private String name;
private String desc; // 描述
// 定义了四个对象,这个时候已经可以使用了
public static final SeasonCopy SPRING = new SeasonCopy("春天", "温暖"); // 创建固定的对象
public static final SeasonCopy WINTER = new SeasonCopy("冬天", "寒冷"); // 创建固定的对象
public static final SeasonCopy SUMMER = new SeasonCopy("夏天", "炎热"); // 创建固定的对象
public static final SeasonCopy AUTUMN = new SeasonCopy("秋天", "凉爽"); // 创建固定的对象
// 构造器
private SeasonCopy(String name, String desc) { // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
this.name = name;
this.desc = desc;
}
// get 步骤二 去掉set相关方法,防止属性被修改
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "SeasonCopy{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
/*
解决方案-枚举
1、枚举对应英文Enumeration,简写为Enum
2、枚举是一组常量的集合
3、可以理解为:枚举属于一种特殊的类,里面只包含一组有限的特定的对象
而枚举有两种实现方式
第一种是自定义类实现枚举
第二种是使用enum关键字实现枚举
*/
// 03
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class Enum03 {
public static void main(String[] args) {
System.out.println(SeasonCopyEnum.SPRING);
System.out.println(SeasonCopyEnum.WINTER);
System.out.println(SeasonCopyEnum.SUMMER);
System.out.println(SeasonCopyEnum.AUTUMN);
}
}
/*
第二种实现枚举的方式是使用关键字
*/
enum SeasonCopyEnum { // 类 ,将其修改成Enum的步骤一----->将class更换成为enum
// private String name;
// private String desc; // 描述
// 定义了四个对象,这个时候已经可以使用了
// 如果使用enum这个关键字来实现枚举-----步骤二将创建的固定对象直接 常量名(参数);
// 如果有多个使用逗号间隔即可。
// 如果使用枚举,要求常量对象写道最前面
// public static final Season SPRING = new Season("春天", "温暖"); // 创建固定的对象
// public static final Season WINTER = new Season("冬天", "寒冷"); // 创建固定的对象
// public static final Season SUMMER = new Season("夏天", "炎热"); // 创建固定的对象
// public static final Season AUTUMN = new Season("秋天", "凉爽"); // 创建固定的对象
SPRING("春天", "温暖"), WINTER("冬天", "寒冷"),
SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽");
private String name;
private String desc; // 描述
// 构造器
private SeasonCopyEnum(String name, String desc) { // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
this.name = name;
this.desc = desc;
}
// get 步骤二 去掉set相关方法,防止属性被修改
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "SeasonCopyEnum{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
// 04
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class EnumDetail04 {
}
enum SeasonCopyEnum04 { // 类 ,将其修改成Enum的步骤一----->将class更换成为enum
// private String name;
// private String desc; // 描述
// 定义了四个对象,这个时候已经可以使用了
// 如果使用enum这个关键字来实现枚举-----步骤二将创建的固定对象直接 常量名(参数);
// 如果有多个使用逗号间隔即可。
// 如果使用枚举,要求常量对象写道最前面
// public static final Season SPRING = new Season("春天", "温暖"); // 创建固定的对象
// public static final Season WINTER = new Season("冬天", "寒冷"); // 创建固定的对象
// public static final Season SUMMER = new Season("夏天", "炎热"); // 创建固定的对象
// public static final Season AUTUMN = new Season("秋天", "凉爽"); // 创建固定的对象
SPRING("春天", "温暖"), WINTER("冬天", "寒冷"),
SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽"),
What(), How; // 这里就是调用的无参构造器,还可以去掉小括号
private String name;
private String desc; // 描述
// 构造器
private SeasonCopyEnum04(String name, String desc) { // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
this.name = name;
this.desc = desc;
}
SeasonCopyEnum04() {} // 无参构造器
// get 步骤二 去掉set相关方法,防止属性被修改
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "SeasonCopyEnum{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
/*
1、当我们使用enum关键字开发一个枚举类的时候,默认会继承Enum类
等会要使用一个工具来证明,javap工具
如果开发了一个Java文件,Hello.java
使用了一个编译工具Javac,生成Hello.class
通过Javap可以反编译成为Java文件,因为上一个文件使用过枚举,我们在
Out文件夹中的可以根据当前包找到对应的class文件,
即SeasonCopyEnum.class文件 Show in Explorer,在资源管理器中打开
然后cmd
javap SeasonCopyEnum.class
Compiled from "Enum03.java"
final class com.alice.innerclass_.innerclass02.SeasonCopyEnum extends java.lang.Enum
<com.alice.innerclass_.innerclass02.SeasonCopyEnum> {
public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum SPRING;
public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum WINTER;
public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum SUMMER;
public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum AUTUMN;
public static com.alice.innerclass_.innerclass02.SeasonCopyEnum[] values();
public static com.alice.innerclass_.innerclass02.SeasonCopyEnum valueOf(java.lang.String);
public java.lang.String getName();
public java.lang.String getDesc();
public java.lang.String toString();
static {};
}
可以看到当前这个class文件编译自Enum03.java
继承了java.lang.Enum
并且是一个final的类
定义的四个常量对象还是static final的
还有一些隐藏的
以上说明了
当我们使用enum关键字开发一个枚举类的时候,默认会继承Enum类
而是一个final类
2、传统的public static final Season2 SPRING = new Season2("春天", "温暖");
简化成了SPRING("春天","温暖");
这里必须要知道,它调用的是哪个构造器
3、如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
What(), How; // 这里就是调用的无参构造器,还可以去掉小括号
4、当有多个枚举对象的时候,使用逗号间隔,最后一个有分号结束
5、枚举对象必须放到枚举类的行首
*/
// 05
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class EnumTest05 {
}
/**
* 第一题
* 下面代码是否正确,并说明表示的含义?
*/
enum Gender { // 正确,使用关键字实现枚举类
BOY, GIRL; // 正确,调用了Gender的默认无参构造器
}
/**
* 第二题
* Gender2 boy = Gender2.BOY;
* Gender2 boy2 = Gender2.BOY;
* System.out.println(boy); // 这里的本质就是调用Gender2的父类的toString方法
* // 前面说过,这里会继承一个叫做java.lang.Enum的这个类
* // 看这个的父类是如何定义的,而这里的父类其实就是return name
* // 所以这里输出的是BOY
* System.out.println(boy2 == boy); // T,因为枚举是静态的,所以是同一个对象
* 相当于
* final class Gender2 extends Enum<Gender2> {
* public static final Gender2 BOY = new Gender2("BOY", 0);
* public static final Gender2 GIRL = new Gender2("GIRL", 1);
* // ...
* }
* 所以返回的是名字BOY
*/
enum Gender2 {
BOY, GIRL;
}
// 06
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class EnumMethod06 {
public static void main(String[] args) {
SeasonCopyEnum06 autumn = SeasonCopyEnum06.AUTUMN; // 得到一个枚举对象
System.out.println(autumn.name()); // 可以获得当前枚举对象的名称
System.out.println(autumn.ordinal()); // 输出的是该枚举对象的次序,也就是第几个,默认从零开始编号
// SeasonCopyEnum06.values(); // 这里values隐藏起来了,源码中没有这个
// 可以从反编译可以看到返回的是一个数组,该数组含有定义的所有枚举对象。
SeasonCopyEnum06[] values = SeasonCopyEnum06.values();
for (int i = 0; i < values.length; i++) {
System.out.print(values[i] + " ");
}
System.out.println();
// 或者使用增强for循环
for (SeasonCopyEnum06 value: values) { // 就是不断从数组中直接取出元素怼到value中
System.out.print(value.name() + " ");
}
System.out.println();
SeasonCopyEnum06 autumn1 = SeasonCopyEnum06.valueOf("AUTUMN");
// SeasonCopyEnum06 autumn1 = SeasonCopyEnum06.valueOf("XXX"); // 找不到会报错
// valueOf是将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常
// 先根据你输入的名称到SeasonCopyEnum06的枚举对象查找,如果找到就返回
// 如果没有找到就报错
System.out.println("autumn1=" + autumn1);
System.out.println(autumn == autumn1); // 这两个指的是同一个枚举对象
System.out.println(SeasonCopyEnum06.AUTUMN.compareTo(SeasonCopyEnum06.SUMMER));
// return self.ordinal - other.ordinal;
// 将两个枚举类型的编号进行比较,直接看最关键的部分就是使用这两个编号进行减3-2
/*
总结:
1、toString:Enum类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息。
2、name可以返回当前对象名,子类中不能重写
3、ordinal:返回当前对象的位置,默认从零开始
4、valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常。
5、values:返回当前枚举类中所有的常量
6、compareTo,比较两个枚举常量,比较的是编号。
*/
}
}
enum SeasonCopyEnum06 {
SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), // 01
SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽"); // 23
private String name;
private String desc; // 描述
// 构造器
private SeasonCopyEnum06(String name, String desc) { // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
this.name = name;
this.desc = desc;
}
SeasonCopyEnum06() {} // 无参构造器
// get 步骤二 去掉set相关方法,防止属性被修改
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "SeasonCopyEnum{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
/*
说明:使用关键字enum时,会隐式继承Enum类,我们就可以使用Enum类的相关方法
*/
// 07
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class EnumExercise07 {
public static void main(String[] args) {
// 获取到所有的枚举对象,即返回数组
Week[] weeks = Week.values();
// 遍历输出
System.out.println("===所有星期的信息如下===");
for (Week week : weeks) {
System.out.println(week);
}
}
}
enum Week {
// 定义Week的枚举对象
MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),
FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期天");
private String name;
private Week(String name) { // 不能new创建对象设置为private
this.name = name;
}
@Override
public String toString() {
return name;
}
}
/*
1、声明Week枚举类,其中包含星期一到星期日的定义;
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
2、使用values返回所有枚举数组,并遍历,输出
*/
// 08
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
/*
enum实现接口
1、使用enum关键字之后,就不能再继承其他类了,因为enum会隐式继承Enum,
Java是单继承机制。
2、枚举类和普通类一样,可以实现接口,如下的形式
enum 类名 implements 接口1,接口2{}
*/
//// 1、错误写法
//class A {
//
//}
//enum Season3 extends A {
//
//}
// 2、依然可以实现接口
public class EnumInterface08 {
public static void main(String[] args) {
Music.CLASSICMUISC.playing();
}
}
interface IPlaying {
public void playing();
}
enum Music implements IPlaying{
CLASSICMUISC;
@Override
public void playing() {
System.out.println("播放好听的音乐。");
}
}
二、注解(了解)
// 09
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class Annotation09 {
public static void main(String[] args) {
}
}
class Father {
public void fly() {
System.out.println("Father fly...");
}
}
class Son extends Father {
@Override // 1这个注解放到了fly方法上面,表示子类的fly方法重写了父类的fly
public void fly() {
// 2如果这里没有写这个注解也还是重写了父类的fly
// 3要这个东西有什么用呢?这个Override的价值在什么地方?
// 如果写了这个注解,编译器就会检查是否真的重写了,如果确实重写了则编译通过,如果没有构成重写,则编译错误
System.out.println("Son fly...");
}
// @Override
// public void say() {} // 这里没有构成重写所以这里会有一个红色波浪线,你编译的时候就要报错。
// 相当于是一个检查,这里父类根本就没有这个方法
/*
public @interface Override {
}
看到源码是这样的一个东西,这里的@interface表示是一个注解类,而不是接口
也就是@interface不是interface,是一个注解类,在JDK5.0的时候进入进去的。
*/
}
/*
1注解Annotation也被称为元数据Metadata,用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。
2和注释一样,注解不会影响程序逻辑,但注解可以被编译或者运行,相当于嵌入在代码中的补充信息。
3在JavaSE中,注解的使用目的比较简单,例如标记过失的功能,忽略警告等。在JavaEE中注解占据了更加重要的角色,
例如用来配置应用程序的任何切面,代替Java EE旧版中所遗留的繁冗代码和XML配置等。
使用Annotation时要在其前面增加@符号,并且将该Annotation当成一个修饰符使用,用于修饰它支持的程序元素
三个基本的Annotation:
1、@Override:限定某个方法,是重写父类方法,该注解只能用于方法
2、@Deprecated:用于表示某个程序元素(类,方法等)已过时。
3、@SuppressWarnings:抑制编译器警告。
*/
// 10
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
/*
Override使用说明
1、@Override表示指定重写父类的方法(从编译层面验证),如果父类中没有fly方法,则会报错
2、如果不写@Override注解,而父类仍有public void fly() {},仍然构成重写。
3、@Override只能修饰方法,不能修饰其他类,包,属性等等
4、查看@Override注解源码为
@Target(ElementType.METHOD),说明只能修饰方法
5、@Target是修饰注解的注解,称为元注解
*/
class AA {
void a() {}
}
//@Override // 只能修饰方法,因为底层源码
class BB extends AA {
/*
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
底层源码说明元素类型是一个METHOD,只能修饰方法
而使用这个Target修饰了注解,说明这是一个元注解
*/
@Override
void a() {
super.a();
}
}
public class Annotation10 {
public static void main(String[] args) {
// A a = new A(); // 这里会出现删除线
A a = new A(); // 虽然过时了但是仍然可以使用只是不推荐使用
a.hi();
System.out.println(a.n1);
}
}
// @Deprecated,使用这个修饰一个类,表示这个类已经过时了。
// 当我们使用这个类用来创建对象的时候,这个时候就会出现删除线
// @Deprecated可以修饰某个元素,表示这个元素已经过时了,不仅仅可以修饰类
// 即使不推荐使用,但是仍然可以使用
/*
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
这个是这个注解的源码,这个源码中的确是一个注解,为什么呢?因为使用的是@interface来进行修饰
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
这里指明了可以在什么地方使用这个注解
构造器,字段,局部变量,方法,包,参数,类,这里的TYPE指的是class类
除此之外其他的地方不能使用了
这个注解可以用来做一个过度
比如我们这里JDK8,以后可能升级到JDK11
在JDK8中写的代码中有一个类,比如说是A类,如果以后要升级到JDK11是一个B类
就可以告诉一下
即:版本升级
小结:
@Deprecated
1、用于表示某个程序元素(类或者方法等)已经过时了
2、可以修饰方法,类,字段,包,参数等等
3、@Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,
PACKAGE,PARAMETER,TYPE})
4、@Deprecated的作用可以做到旧版本的兼容和过渡。
*/
@Deprecated
class A {
@Deprecated
public int n1 = 10; // Deprecated修饰成员变量
@Deprecated
public void hi() { // Deprecated不仅仅可以修饰类,还可以修饰其他的,比如方法,在使用这个方法的时候就会出现删除线
System.out.println("你好,这里是A中的方法hi()"); // 但是仍然可以使用
}
}
// 11
package com.alice.innerclass_.innerclass02;
import java.util.ArrayList;
import java.util.List;
/**
* @author alice_huijing
* @version 1.0
*/
//@SuppressWarnings({"rawtypes", "unchecked", "unused"}) // 直接给类添加抑制信息
public class Annotation11 {
@SuppressWarnings({"rawtypes", "unchecked", "unused"}) // 在大括号中可以写入希望抑制的,也就是不显示的警告信息
public static void main(String[] args) {
List list = new ArrayList();
list.add("A"); //0
list.add("B"); //1
list.add("C"); //2
int i;
System.out.println(list.get(1));
/*
当我们不想看到这些警告的时候,可以使用SuppressWarnings注解抑制这些警告信息
具体可以抑制哪些信息,老韩提供了一个文档
SuppressWarning中的属性介绍以及属性的说明.txt
比如all可以抑制所有的警告,原本有六个警告,全部写上去之后这些警告就直接消除了。
我们可以将鼠标放到这些黄色的部分看看出现什么警告,对应出现的警告,可以在文档中
查找到对应的抑制功能,做到精确的抑制
比如List list = new ArrayList();这里是一个
Raw use of parameterized class 'ArrayList'
从这里我们可以发现有一个Raw的单词
我们可以使用rawtypes来抑制,这里和泛型有关系,等讲到泛型的时候还会讲解。
再比如后面的add
这里没有进行类型的检查
Unchecked call to 'add(E)' as a member of raw type 'java.util.List'
只需要填入unchecked
还有一个警告
Variable 'i' is never used
i这个没有使用
可以使用unused来抑制
关于这个的作用范围和你放的位置有关
现在将这个放到main方法上面,这个作用的范围就是再main方法中
如果写另外一个方法f1,这里就管不住了。
当然我们可以采取同样的操作进行抑制
直接添加注解即可。
如果想要将这个类中的所有警告全部抑制,只需要给类添加即可。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
我们可以放到类,字段,方法,参数。。
这里的value表示传的时候可以传一个数组进去。
可以指定多种要抑制的数据
*/
}
public void f1() { // 因为管的是main,所以这里直接提出警告,另外这个注解是可以放到一条语句上面的。
@SuppressWarnings({"rawtypes"})
List list = new ArrayList();
list.add("A"); //0
list.add("B"); //1
list.add("C"); //2
@SuppressWarnings({"unused"})
int i;
System.out.println(list.get(1));
}
}
// 在平时我们写代码的时候会容易出现一些警告信息,这些警告并不是说我们的代码不能使用了,依然可以运行
/*
小结:
1、unchecked是忽略没有检查的警告
2、rawtypes是忽略没有指定泛型的警告,传参的时候没有指定泛型的警告
3、unused是忽略没有使用某个变量的警告错误
4、@SuppressWarnings可以修饰的程序元素为,查看@Target
5、生成@SupperssWarnings时,不用背,直接点击左侧的黄色提示就可以选择(注意可以指定生成的位置)。
*/
// 12
package com.alice.innerclass_.innerclass02;
/**
* @author alice_huijing
* @version 1.0
*/
public class Annotation12 {
public static void main(String[] args) {
}
}
class OO {
public void xx() {
System.out.println("OO xx");
}
}
@Deprecated
class O extends OO{
@Deprecated
public int n1 = 10;
@Override
public void xx() {
System.out.println("O xx");
}
/*
这里的Override的策略就是
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
可以看到策略是SOURCE,所以只是在编译器层面,或者说是源码的层面生效
}
点到这里的Target中看
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
看到ElementType中,可以支持这些程序元素
public enum ElementType {
TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,
ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE
}
@Deprecated
比如像这种很多地方都可以使用
但是@Override在类上面不能使用
因为@Target(ElementType.METHOD),Override只允许在方法层面
而@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
可以在TYPE,也就是可以在类上
*/
}
/*
有关JDK的元Annotation,元注解的介绍
元注解的基本介绍:
JDK的元Annotation用于修饰其他Annotation
元注解:本身作用不大,讲解这个的原因是希望大家看源码的时候就可以知道他是干什么的。
元注解的种类(使用不多,了解,不用深入研究)
1、Retention //指定注解的作用范围,三种SOURCE,CLASS,RUNTIME,即源码,类型,运行时
2、Target // 指定注解可以在哪些地方使用
3、Documented指定该注解是否会在Javadoc体现
4、Inherited // 子类会继承父类注解
即:
1)元注解是修饰注解的注解
@Retention注解
说明:
只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间,
@Retention包含一个RetentionPolicy类型的成员变量,使用@Rentention
时必须为该Value成员变量指定值:
@Retention的三种值
1、RetentionPolicy.SOURCE:编译器使用之后,直接丢弃这种策略的注解
2、RetentionPolicy.CLASS:编译器将把注解记录在class文件中,当运行Java程序时,
JVM不会保留注解,这是默认值。
3、RetentionPolicy.RUNTIME:编译器将把注解记录在class文件中,当运行Java程序时
,JVM会保留注解,程序可以通过反射获得该注解。
这里给出一张图
@Target
这里基本说明
用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰哪些程序元素,@Target也包含一个名为
value的成员变量
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
在Deprecated中有@Documented,到时候生成JavaDOC这里的Deprecated会保留到生成的Java文档上
比如在String这个类里面有一个过时的方法
比如getBytes,这个方法上面会显示有@Deprecated
@Inherited注解
被它修饰的Annotation将具有继承的特性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解
*/
三、附图
![image]()