JAVA高级(四)

枚举类的使用

主要内容:

        如何自定义枚举类

        如何使用关键字enum定义枚举类

        Enum类的主要方法

        实现接口的枚举类

使用

1.枚举类的理解:类的对象只有有限个,确定的。

2.当需要定义一组常量时,强烈建议使用枚举类

举例

        星期:Monday(星期一)、......、Sunday(星期天)

        性别:Man(男)、Woman(女)

3.如果枚举类中只有一个对象,则可以作为单例模式的实现方式

定义

方式一:JDK5.0之前,自定义枚举类

        1.声明Season对象的属性
        2.私有化类的构造器,并给对象属性赋值
        3.提供当前枚举类的多个对象
        4.其他诉求:获取枚举类对象的属性、提供toString()
package com.xxx.java;

/**
 * @author Alkaid
 * @create 2022-08-17 0:25
 */
public class SeasonTest {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring);
    }
}

//自定义枚举类
class Season {
    //1.声明Season对象的属性
    private final String seasonName;
    private final String seasonDesc;


    //2.私有化类的构造器,并给对象属性赋值
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //3.提供当前枚举类的多个对象
    public static final Season SPRING = new Season("春天","春暖花开");
    public static final Season SUMMER = new Season("夏天","夏日炎炎");
    public static final Season AUTUMN = new Season("秋天","秋高气爽");
    public static final Season WINTER = new Season("冬天","冰天雪地");

    //4.其他诉求:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //4.其他诉求:提供toString()

    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}


方式二:JDK5.0,可以使用enum关键字定义枚举类

说明:定义的枚举类默认继承于java.lang.Enum,其父类重写了toString()打印当前常量名

1.提供当前枚举类的多个对象,多个对象之间用“,”隔开,末尾对象“;”结束

                添加()代表调用构造器,添加{}可以重写实现的接口的方法

2.声明Season对象的属性
3.私有化类的构造器,并给对象属性赋值
4.其他诉求:获取枚举类对象的属性

Enum类的主要方法

values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。

valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符 串必须是枚举类对象的“名字”。如不是,会有运行时异常: IllegalArgumentException。

toString():返回当前枚举类对象常量的名称

使用enum关键字定义的枚举类实现接口

        情况一:实现接口,在enum类中实现抽象方法

        情况二:让枚举类的对象分别实现接口中的抽象方法

package com.xxx.java;

/**
 * @author Alkaid
 * @create 2022-08-17 0:38
 */
public class SeasonTest1 {
    public static void main(String[] args) {
        Season1 summer = Season1.SUMMER;
        //toString()
        System.out.println(summer);

//        System.out.println(Season1.class.getSuperclass());

        //values()
        Season1[] values = Season1.values();
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);
            values[i].show();
        }

        Thread.State[] values1 = Thread.State.values();
        for (int i = 0; i < values1.length; i++) {
            System.out.println(values1[i]);
        }

        //valueof(String objName)返回枚举类中对象名是objName的对象
        //如果没有objName的枚举类对象,则抛异常IllegalArgumentException
        Season1 winter = Season1.valueOf("WINTER");
        System.out.println(winter);

        winter.show();
    }
}


interface Info{
    void show();
}
//使用enum关键字定义枚举类
enum Season1 implements Info{
    //1.提供当前枚举类的多个对象,多个对象之间用“,”隔开,末尾对象“;”结束
    SPRING("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("春天在哪里");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        @Override
        public void show() {
            System.out.println("宁夏");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        @Override
        public void show() {
            System.out.println("秋天不回来");
        }
    },
    WINTER("冬天","冰天雪地"){
        @Override
        public void show() {
            System.out.println("大约在冬季");
        }
    };

    //2.声明Season对象的属性
    private final String seasonName;
    private final String seasonDesc;


    //3.私有化类的构造器,并给对象属性赋值
    private Season1(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4.其他诉求:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    @Override
    public void show() {
        System.out.println("这是一个季节");
    }

    //4.其他诉求:提供toString()

//    @Override
//    public String toString() {
//        return "Season1{" +
//                "seasonName='" + seasonName + '\'' +
//                ", seasonDesc='" + seasonDesc + '\'' +
//                '}';
//    }
}

注解(Annotation)

主要内容:

        注解(Annotation)概述

        常见的Annotation示例

        自定义Annotation

        JDK中的元注解

        利用反射获取注解信息(在反射部分涉及)

        JDK 8中注解的新特性

注解(Annotation)概述

JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注解)

Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation, 程序员 可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。代 码分析工具、开发工具和部署工具可以通过这些补充信息进行验证 或者进行部署

Annotation 可以像修饰符一样被使用, 可用于修饰包,类, 构造器, 方 法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在 Annotation 的 “name=value” 对中。

在JavaSE中,注解的使用目的比较简单,例如标记过时的功能, 忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如 用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗 代码和XML配置等。

未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以 上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的 Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上 可以说:框架 = 注解 + 反射 + 设计模式

常见的Annotation示例

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成 一个修饰符使用。用于修饰它支持的程序元素

示例一:生成文档相关的注解

        @author 标明开发该类模块的作者,多个作者之间使用,分割

        @version 标明该类模块的版本

        @see 参考转向,也就是相关主题

        @since 从哪个版本开始增加的

        @param 对方法中某参数的说明,如果没有参数就不能写

        @return 对方法返回值的说明,如果方法的返回值类型是void就不能写

        @exception 对方法可能抛出的异常进行说明 ,如果方法没有用throws显式抛出的异常就不能写 其中

                @param @return 和 @exception 这三个标记都是只用于方法的。

                @param的格式要求:@param 形参名 形参类型 形参说明

                @return 的格式要求:@return 返回值类型 返回值说明

                @exception的格式要求:@exception 异常类型 异常说明

                @param和@exception可以并列多个

示例二:在编译时进行格式检查(JDK内置的三个基本注解)。        

        @Override: 限定重写父类方法, 该注解只能用于方法

        @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为 所修饰的结构危险或存在更好的选择

        @SuppressWarnings: 抑制编译器警告

示例三:跟踪代码依赖性,实现替代配置文件功能

如何自定义注解

定义新的 Annotation 类型使用 @interface 关键字

Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、 以上所有类型的数组。

可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字

如果只有一个参数成员,建议使用参数名为value

如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名 = 参数值” ,如果只有一个参数成员,且名称为value, 可以省略“value=

没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation

注意:自定义注解必须配上注解的信息处理流程(反射)才有意义。

总结为:

        使用 @interface 关键字

        只有一个参数成员,建议使用参数名为value

        指定成员变量的初始值可使用 default 关键字

        没有成员定义的 Annotation 称为标记

注意:

        定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值

        自定义注解必须配上注解的信息处理流程(反射)才有意义。

        自定义注解通常都会指明两个元注解:Retention、Target

JDK 中的元注解

JDK 的元 Annotation 用于修饰其他 Annotation 定义

元注解:对现有的注解进行解释说明的注解

JDK5.0提供了4个标准的meta-annotation类型,分别是:

        Retention:指定所修饰的 Annotation 的生命周期:SOURCE/CLASS(默认行为)/RUNTIME

                        只有声明为RUNTIME生命周期的注解,才能通过反射获取。

        Target:指定被修饰的 Annotation 能用于 修饰哪些程序元素。

出现频率较低的

        Documented:表示所修饰的注解在被javadoc解析时,保留下来

        Inherited:被它修饰的 Annotation 将具有继承性

元数据的理解:

String name = “atguigu”;

JDK8中注解的新特性

Java 8对注解处理提供了两点改进:可重复的注解及可用于类型的注解。

可重复注解

        1.在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class

        2.MyAnnotation的元注解和Myannotations的都要相同

        3.然后就可以在需要使用的位置重复注解

类型注解

        ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语 句中(如:泛型声明)。

        ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

package com.xxx.java1;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Date;

/**
 * @author Alkaid
 * @create 2022-08-17 13:19
 */
public class AnnotationTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.walk();

        Date date = new Date(2022, 9, 30);
        System.out.println(date);

       @SuppressWarnings("unused")
        int n = 10;

        @SuppressWarnings({"unused","rawtypes"})
        ArrayList list = new ArrayList();
    }

    @Test
    public void testGetAnnotation(){
        Class clazz = Student.class;
        Annotation[] annotations = clazz.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            System.out.println(annotations[i]);
        }

    }
}

//jdk8之前的写法
//@MyAnnotations({@MyAnnotation(value = "hi"),@MyAnnotation(value = "abc")})

@MyAnnotation(value = "hi")
@MyAnnotation(value = "abc")
class Person implements Info{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void walk(){
        System.out.println("人走路");
    }

    public void eat(){
        System.out.println("人吃饭");
    }

    @Override
    public void show() {

    }
}

interface Info{
    void show();
}

class Student extends Person{
    @Override
    public void walk() {
        System.out.println("学生走路");
    }
}

//类型注解
class Generic<@MyAnnotation T>{
    public void show() throws @MyAnnotation RuntimeException{
        ArrayList<@MyAnnotation String> list = new ArrayList<>();

        int num = (@MyAnnotation int)10L;
    }
}
package com.xxx.java1;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

/**
 * @author Alkaid
 * @create 2022-08-17 13:38
 */
@Inherited
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
public @interface MyAnnotation {
    String value() default "hello";
}
package com.xxx.java1;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

/**
 * @author Alkaid
 * @create 2022-08-17 14:14
 */
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

public @interface MyAnnotations {
    MyAnnotation[] value();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值