JavaSE(十九)枚举&注解

本文介绍了Java中的枚举类型,强调其固定对象和单例设计,以及如何通过枚举实现单例模式。同时,讲解了注解和元注解的概念,包括它们的作用和使用场景,以及如何通过反射解析自定义注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式 单例 单个实例 某种类型只能有单个对象

1.枚举类型

  • 此种类型的对象 指定个数个 对象;对象是固定的 固定就那么几个 对象都是提前定义好的;季节类型 春夏秋冬 时间单位类型 省份类型 颜色类型;

  • Java 枚举是一个特殊的类型,一般表示一组常量(一批对象 固定好的对象称之为一组常量),比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

  • 枚举类型,本质就是个class 而且是一个是继承了Enum类的类型

  • 对象都是提前定义好的 固定死的;实例和实例之间使用逗号隔开 最后一个实例使用分号;只需要写对象(实例)名称;常量名称一般都是大写;对象的声明必须在首行;

  • 枚举类型的构造器默认全部都是私有化的 而且必须是private修饰

//枚举类型,本质就是个class 而且是一个是继承了Enum类的类型
public enum JiJie {
    //对象都是提前定义好的 固定死的;实例和实例之间使用逗号隔开 最后一个实例使用分号;
    //只需要写对象(实例)名称;常量名称一般都是大写
    // 对象的声明必须在首行
//    CHUN, XIA, QIU, DONG;
//    CHUN(), XIA(), QIU(), DONG();//调用无参构造创建对象 小括号可以省略
//    CHUN, XIA("夏天"), QIU("秋天"), DONG;//调用有参构造创建对象 需要传递对应的实参
    CHUN, XIA("夏天") {
        //花括号出现是 为了重写外部的方法
        @Override
        public String getName() {
            return "夏天重写的代码";
        }
    }, QIU("秋天"), DONG;
​
    private String name;
​
    //枚举类型的构造器默认全部都是私有化的 而且必须是private修饰
    private JiJie() {
    }
​
    private JiJie(String name) {
        this.name = name;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
}

1,枚举类型的基本使用

/**
     * 枚举类型的基本使用
     */
    private static void method1() {
        JiJie chun1 = JiJie.CHUN;
        JiJie chun2 = JiJie.CHUN;
        JiJie xia = JiJie.XIA;
        System.out.println(chun1 == chun2);
        System.out.println(chun1);
        System.out.println(chun1.getName());
        System.out.println(xia.getName());
        //通过继承获取的方法
        System.out.println("name" + xia.name());
        //对象的序号从0开始
        System.out.println("序号:" + xia.ordinal());
    }

2,在switch中的使用

  /**
     * 枚举类型在switch中应用
     *
     * @param jiJie
     */
    private static void method2(JiJie jiJie) {
        switch (jiJie) {
            case CHUN:
                System.out.println("");
                break;
            case XIA:
                System.out.println("");
                break;
            case QIU:
                System.out.println("");
                break;
            case DONG:
                System.out.println("");
                break;
            default:
                System.out.println("");
                break;
        }
    }

3,枚举去设计单例

  • 不管是反射还是反序列化都无法破坏 使用枚举设计的单例

​
public enum Singleton {
    //单个实例
    INSTANCE;
}
​

验证代码

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./res/out.txt"));
             ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./res/out.txt"))) {
            Singleton instance = Singleton.INSTANCE;
            objectOutputStream.writeObject(instance);
​
            System.out.println("=======");
            Object o = objectInputStream.readObject();
            System.out.println(o);
            System.out.println(instance);
​
            System.out.println(o == instance);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    private static void method4() throws ClassNotFoundException, NoSuchMethodException {
        Class<?> aClass = Class.forName("com.edu.www.day0512.Singleton");
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
    }

低耦合 高内聚

框架的配置文件 XML

.xml配置文件 ;灵活 低耦合的配置 ;维护成本过高

注解的出现 把要配置的信息直接写入源码中 耦合度增加了 维护成本降低了;

2.注解

  • 注解 可以使用在 类,方法上 成员变量;

  • @Override;必须要有解析程序 如果没有解析程序 注解毫无作用

  • 一类实在编译阶段被解析 一类是在运行阶段通过反射被解析

  • 内置注解 提供好的可以直接使用的;自定义注解

  • 注解的本质是接口类型,而且是继承了Annotation接口的接口类型

  • 元注解 注解的注解 用来声明注解的

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
    
}
public interface Override extends Annotation{
​
}

1,元注解

@Target,此注解可以使用在哪些地方

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,
    }

@Retention:保留 期 表示这个注解能活多久

public enum RetentionPolicy {
    /**
     * 只存在与源文件中 
     */
    SOURCE,
​
    /**
     *可存在与 字节码文件中
     */
    CLASS,
​
    /**
   * 可存活与 运行期
     */
    RUNTIME
​

@Documented:此注解信息 是否要出现在JavaDoc 文档中

@Inherited:可以被继承的注解;子类可以直接继承父类上面的注解

2.1.自定义注解

1,基本使用

//注解类型
//@Target(ElementType.TYPE)
@Target({ElementType.TYPE, ElementType.METHOD})
//@Retention(value = RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
    //注解中的成分只有一个 而且名称是value的时候在进行使用的时候可以直接赋值 value可以省略
//    String value();
​
    //基本数据类型,String,Class enum,Annotation;这写类型的数组也可以
    String name();
​
    String email();
}

应用

@Description(name = "father", email = "aa")
@Ano2
public class Father {
​
    @Description(name = "study", email = "aa")
    public void study() {
​
    }
}
​

解析程序

 /**
     * 使用反射解析程序
     *
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     */
    private static void method1() throws ClassNotFoundException, NoSuchMethodException {
        Class<?> aClass = Class.forName("com.edu.www.day0512.anno1.Father");
        //获取的是此类型上面 标注的所有注解
        Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        // 获取指定注解对象
        Description annotation = aClass.getAnnotation(Description.class);
        String name = annotation.name();
        System.out.println(name);
        String email = annotation.email();
        System.out.println(email);
​
        //获取方法上面的注解
        Method declaredMethod = aClass.getDeclaredMethod("study");
        Description annotation1 = declaredMethod.getAnnotation(Description.class);
    }

2,测试框架的使用

自定义注解类型

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestEnable {
}

应用

public class Student {

    @TestEnable
    public void method1() {
        System.out.println("method1");
    }

    public void method2() {
        System.out.println("method2");
    }

    @TestEnable
    public void method3() {
        System.out.println("method3");
    }

    public void method4() {
        System.out.println("method4");
    }
}

解析程序

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class<?> aClass = Class.forName("com.edu.www.day0512.anno2.Student");
        Object o = aClass.newInstance();

        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {

            if (declaredMethod.isAnnotationPresent(TestEnable.class)) {

                declaredMethod.invoke(o);
            }
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值