类.成员名
调用成员变量,因此,成员必须是共有的// 自定义枚举类
class Season{
// 1. 声明Season对象的属性
private final String season ;
// 2. 私有化类的有参构造器
private Season(String season){
this.season = season;
}
// 3. 定义当前枚举类的多个对象:public static final
public static final Season SPRING = new Season("Spring");
public static final Season SUMMER= new Season("Summer");
public static final Season FALL= new Season("Fall");
public static final Season WINTER= new Season("Winter");
// 4.1 对象属性的get()
public String getSeason(){
return this.season;
}
// 4.2 提供toString方法
@Override
public String toString() {
return "Season{" +
"season='" + season + '\'' +
'}';
}
}
enum Week{
// 1. 提供当前枚举类的对象,多个对象之间用","隔开,末尾对象使用";"结束
MONDAY("星期一") ,
TUDEDAY("星期二"),
WEDNESAY("星期三"),
THURSDAY("星期四"),
FRIDAY("星期五"),
STAURDAY("星期六"),
SUNDAY("星期天");
// 2. 声明当前枚举类的属性,使用private final修饰
private final String weekInfo;
// 3. 提供带参构造方法
private Week(String str) {
this.weekInfo = str;
}
// 4. 提供使用的方法
public String getWeekInfo() {
return this.weekInfo;
}
}
values()
:返回枚举类型的对象数组。该方法可以很方便第遍历所有的枚举值valueOf(String objName)
:返回枚举类中对象名是objName的对象;如果没有objName的枚举类对象,则抛出异常:IllegalArgumentException public String toString()
:返回枚举对象的对象名(java的Enum类进行改写后的toString(),自定义枚举类可以进行重写)常用方法测试:
@Test
public void testEnumMethdo(){
// 1. 返回枚举类所有成员的对象数据
Week[] values = Week.values();
for (Week value : values) {
// 2. 对枚举类对象进行输出,自动调用toString()方法
System.out.println(value);
}
// 3. 调用valueOf方法返回指定对象名的枚举类对象
// Week monday = Week.valueOf("Monday"); // 对象名称严格区分大小写
Week monday = Week.valueOf("MONDAY");
System.out.println("monday = " + monday);
}
enum EnumClass implements Host{
QITIYUANLIU("气体源流"){
@Override
public String showHost() {
return "张楚岚";
}
},
JULINGQIANJIANG("拘灵遣将"){
@Override
public String showHost() {
return "风星瞳";
}
},
TONGTIANLU("通天箓"){
@Override
public String showHost() {
return "张灵玉";
}
},
FENGHOUQIMEN("风后奇门"){
@Override
public String showHost() {
return "王也";
}
},
SHENJIBAILIAN("神级百炼"){
@Override
public String showHost() {
return "马仙洪";
}
},
DALUODONGGUAN("大罗洞观"){
@Override
public String showHost() {
return "谷畸亭";
}
},
LIUKUXIANZEI("六库仙贼"){
@Override
public String showHost() {
return "巴伦";
}
},
SHUANGQUANSHOU("双全手"){
@Override
public String showHost() {
return "吕良";
}
};
private String name ;
EnumClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "EnumClass{" +
"name='" + name + '\'' +
'}';
}
// 使用这种方式,所有的枚举类对象调用产生的都是同一个结果
// @Override
// public void showHost() {
// System.out.println("这是一个把奇技拥有者");
// }
}
@Test
public void testMyEnumClass(){
EnumClass[] values = EnumClass.values();
for (EnumClass value : values) {
System.out.println("绝技:"+value);
System.out.println("拥有者:"+value.showHost());
}
EnumClass daluodongguan = EnumClass.valueOf("DALUODONGGUAN");
System.out.println("daluodongguan = " + daluodongguan);
}
// 结果:
绝技:EnumClass{name='炁体源流'}
拥有者:张楚岚
绝技:EnumClass{name='拘灵遣将'}
拥有者:风星瞳
绝技:EnumClass{name='通天箓'}
拥有者:张灵玉
绝技:EnumClass{name='风后奇门'}
拥有者:王也
绝技:EnumClass{name='神级百炼'}
拥有者:马仙洪
绝技:EnumClass{name='大罗洞观'}
拥有者:谷畸亭
绝技:EnumClass{name='六库仙贼'}
拥有者:巴伦
绝技:EnumClass{name='双全手'}
拥有者:吕良
daluodongguan = EnumClass{name='大罗洞观'}
@Override
: 限定重写父类方法,该注解只能用于方法@Deprecated
:用以表示所修饰的元素已经过时。通常是因为所修饰的机构危险或存在更好的选择SuppressWarnings
:抑制编译器警告元注解是用于修饰其他注解的定义:即对现有的注解进行修饰说明的注解
4个元注解:
@Retention
:指定该注解的生命周期,SOURCE\CLASS(默认行为)\RUNTIME
(只有声明为RUNTIME生命周期的注解,才能通过反射获取)// Retention注解的源码定义
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value(); // 成员为一个枚举类型的变量
}
// 枚举类RetentionPolicy的源码定义
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE, // 表示被修饰的注解的有效期只存在于源代码中,编译后的.class文件通过反编译后无法看到该注解
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS, // 表示被修饰的注解的有效期保留至.class文件,.class文件可见,但对运行无影响
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME // 表示被修饰的注解保留到运行期,被JVM读取,可以通过反射被调用
}
@Target
:用于修饰注解定义,用于指定被修饰的注解能用于修饰那些程序元素,@Target也包含一个名为value的成员变量// target注解的源码定义:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value(); // 成员:枚举数组
}
// ElementType的定义:枚举类,可修饰的元素类型;
ElementType的枚举成员:
1. TYPE:表示类,接口(包含注解类型),枚举类型
2. FIELD: 属性/成员变量(包括枚举常量)
3. METHOD:方法
4. PARAMETER: 参数
5. CONSTRUCTOR:构造器
6. LOCAL_VARIABLE:局部变量
7. ANNOTATION_TYPE:注解类型
8. PACKAGE:包
9. TYPE_PARAMETER:类型参数
10.TYPE_USE:所有使用类型的地方
/*
以上成员表示,如果一个注解被target修饰,且target的值为上述成员的某几
个,则表示被修饰的注解可以使用在上述没u成员所规定的地方
*/
@target注解测试:
// 使用Target注解修饰自定义注解表明该注解可作用的范围:
//类,接口,枚举类,注解,方法,类型参数(泛型)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.TYPE_PARAMETER})
public @interface TestTargetAnnotation {
}
@Documented
:用于指定被该Annotation修饰的Annotation类将被javadoc工具提取成文档。默认情况下,javadoc是不包括注释的
@Inherited
:被他修饰的Annotation将具有继承性。如果某个类使用了被Inherited修饰的注解,则其子类将自动具有该注解
inherited测试:
使用Inherited
修饰自定义的注解,来展现注解的继承性
//
@Inherited
@Target(ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
// 需要对Inherited的继承性进行验证,就需要使用反射,则需要将注解声明周期设置到为运行期
public @interface TestInheritedAnnotation {
String value();
}
// 自定义父类
@SuppressWarnings("unchecked")
@Resource
@TestInheritedAnnotation("对父类进行标记")
public class SuperClass {
}
// 自定义子类
public class SubClass extends SuperClass{
}
@Test
public void client(){
System.out.println("父类的注解:");
Class clazz = SuperClass.class;
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType());
}
System.out.println("子类的注解:");
clazz = SubClass.class;
annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType());
}
}
父类的注解:
interface javax.annotation.Resource
interface 测试inherited注解.TestInheritedAnnotation
子类的注解:
interface 测试inherited注解.TestInheritedAnnotation
@Inherited
修饰的注解,具有继承性,其可以随着子类继承父类,从而标记在子类之上可参考注解@SuppressWarnings
进行定义
自定义注解通常都会指定两个元注解:Retention,Target
@SuppressWarnings的定义
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
// 省略
/**
* The string "unchecked" is used to suppress unchecked warnings.
*/
// 字符串“unchecked”用于抑制未检查的警告。
// 省略
String[] value();
}
自定义的注解:
@interface
进行注解的定义@Target({ElementType.TYPE_USE,})
@SuppressWarnings("unchecked") // 抑制编译器警告
public @interface MyAnnotation {
// 注解的变量后带括号
String name() default "乾之三爻"; // name变量的设有默认值
String[] otherName();
}
// 自定义注解的测试:
@MyAnnotation(otherName = {"初九","风雨飘摇"}) // 对注解数组的赋值
public class TestMyAnnotation {
}
java.lang.annotation.Annotation
接口重复注解:对同一个目标使用多个相同的注解,在JDK8之前,这是不允许的。
直接进行重复注解会报错
自定义注解
// 定义注解1:定义一个实现功能的注解
public @interface MyAnnotation {
String value();
}
// 定义注解2:定义一个注解,负责将上述定义的注解包装为数组变量
public @interface MyAnnotations {
MyAnnotation[] values();
}
使用重复注解:
@MyAnnotations(values = {@MyAnnotation("helloworld"),@MyAnnotation("乾之三爻")}) // JDK8之前的重复注解
public class Client {
}
@Repeatable
对要进行重复注解的注解进行修饰,在本文中,即对@MyAnnotation
进行修饰,并在赋值时,通过反射MyAnnotations.class
与@MyAnnotations
进行绑定依旧定义两个注解,其中一个注解的成员是注解数组,从而对另一个注解进行关联
// 定义注解1:
// 要求两个注解的变量必须是相同的名字
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
// 定义注解2:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
MyAnnotation[] value();
}
使用重复注解
// JDK8之后进行重复注解:
@MyAnnotation("HelloWorld")
@MyAnnotation("QianZhiSanyao")
public class Client {
}
JDK8之后给@Target
注解新增加了两个作用范围,给枚举类ElementType
添加了两个成员
TYPE_PARAMETER
:类型参数,与泛型结合使用TYPE_USE
:使用类型 public <T> void show(@MyAnnotation("TYPE_PARAMETER") T t){
System.out.println(t);
}
public void count(@MyAnnotation("TYPE_USE") int i){
int count = 0 ;
for(@MyAnnotation("TYPE_USE") int j = 0 ; j < i ; j++,i--){
count += j ;
}
System.out.println(count);
}