JAVA基础课程
第十九天 枚举类与注解
枚举类
什么情况使用枚举类
(1)类的对象只有有限个,确定的。
(2)当需要定义一组常量时,强烈使用枚举类
eg:性别,星期等
(3) 如果枚举类只有一个对象,则可以作为单例模式实现
如果自定义枚举类
package com.test.course.enumtest;
/**
* @author PitterWang
* @create 2020/5/7
* @since 1.0.0
*/
public class Season {
public static void main(String[] args) {
System.out.println(Season.AUTUMN.toString());
}
//①声明对象的属性,属性为private final
private final String seasonName;
private final String seasonDesc;
//②创建私有构造器,给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
/***
* ③提供枚举对象:public static final
*/
public static final Season SPRING = new Season("SPRING","春天");
public static final Season SUMMER = new Season("SUMMER","夏天");
public static final Season AUTUMN = new Season("AUTUMN","秋天");
public static final Season WINTER = new Season("WINTER","冬天");
//获取枚举类的属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
如何使用关键字enum定义枚举类
(1)枚举类默认继承java.lang.Enum
package com.test.course.enumtest;
enum Sex {
//定义多个枚举用,隔开,最后用;
/**
* 男
*/
MALE("男"),
/**
* 女
*/
FAMALE("女");
//①声明对象的属性,属性为private final
private final String seasonName;
//创建私有构造器,给对象属性赋值
private Sex(String seasonName){
this.seasonName = seasonName;
}
//获取枚举类的属性
public String getSeasonName() {
return seasonName;
}
@Override
public String toString() {
return "Sex{" +
"seasonName='" + seasonName + '\'' +
'}';
}
}
Enum类的主要方法
values()方法
valueOf(String str)方法
toString方法
Sex sex = Sex.MALE;
System.out.println(sex.getClass().getSuperclass()); //class java.lang.Enum
System.out.println("***********************8");
Sex[] sexes = Sex.values();
for (Sex sex1 : sexes) {
System.out.println(sex1);
System.out.println(sex1.toString());//如果不重写的话返回的value
}
System.out.println("***********************8");
System.out.println(Sex.valueOf("MALE"));
实现接口的枚举类
package com.test.course.enumtest;
public enum Status implements Info{
P(){
@Override
public void show() {
System.out.println("待完成");
}
},
C{
@Override
public void show() {
System.out.println("完成");
}
};
}
interface Info{
void show();
}
注解(Annotation)
注解概述
(1)JDK5开始新增注解
(2)Annotation就是代码中的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应处理。
(3)Annotation可以像修饰符一样,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量等。
(4)在JavaSE中,使用比较简单,做JavaEE时使用比较多。
(5)一定程度上,未来开发模式都是基于注解的。一定程度上说:框架=注解+反射+设计模式。eg:SpringBoot
常见的注解
使用Annotation是时,要在其前面加@,并把Annotation当成一个修饰符使用。
(1)生成文档相关注解
* @author PitterWang
* @create 2020/5/7
* @since 1.0.0
等等。。。。
(2)在编译时,进行格式检查(JDK内置的三个基本注解)
@Override 限定重写父类方法,只能用于方法上
@Deprecated 用于表示所修饰的元素(类,方法等)已经过时。
@SuppressWarnings("") 抑制编译器警告
(3)根据代码依赖性,实现替代配置文件功能
①spring框架等
②Junit单元测试大量的注解
自定义注解
1.注解声明为@interface
2.内部定义成员,通常用value表示
3.可以指定成员默认值,使用default定义
4.如果自定义注解没有成员,表明时一个标识作用
如果注解有成员,使用注解时,需要指明成员的值,自定义注解必须配上注解的信息处理流程(使用反射)才有意义
package com.test.course.annotationtest;
/***
* 自定义注解
* 1.注解声明为@interface
* 2.内部定义成员,通常用value表示
* 3.可以指定成员默认值,使用default定义
* 4.如果自定义注解没有成员,表明时一个标识作用
*/
public @interface MyAnnotation {
String value() default "test";
}
JDK中的元注解
元注解用来修饰其他注解的定义
(1)@Retention():用于修饰一个Annotation定义,用于指定该Annotation的生命周期,@Retention()中的RetentionPolicy类型的成员变量,使用@Retention必须要为该value设指定值
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
* 在源文件中有效
*/
SOURCE,
/**
* 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,
/**
* 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
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
(2)@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();
}
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) 描述域*/
FIELD,
/** Method declaration 方法*/
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration 构造器*/
CONSTRUCTOR,
/** Local variable declaration 局部变量*/
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration 包 */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
(3)@Documented用于修饰的注解将被javadoc工具提成文档,默认不包括文档
(4)@Inherited:被他修饰的注解将具有继承性,如果某个类被使用了被@Inherited修饰的注解,则其子类将自动具有该注解。
利用反射获取注解信息
注意,注解MyAnnotation 必须修饰 @Retention(RetentionPolicy.RUNTIME)。
public class AnnotationTest {
public static void main(String[] args) {
Class clazz = Persion.class;
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
}
}
@MyAnnotation(value = {"hello","test"})
class Persion{
@MyAnnotation
Persion(){
}
@MyAnnotation("2")
private int age;
@MyAnnotation("name")
private String name;
}