Java.第 11 章枚举和注解.课堂笔记

第11 章 枚举和注解

11.1 先看一个需求

要求创建季节(Season) 对象,请设计并完成。

 class Season
 {						//类 
     private String name; 
     private String desc;//描述 
     //构造器 
     //getXX 
     //setXX 
 } 

代码:

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class Enumeration01
{
    public static void main(String[] args) {
         Season spring = new Season("春天", "温暖");
         Season winter = new Season("冬天", "寒冷");
         Season summer = new Season("夏天", "炎热");
         Season autumn = new Season("秋天", "凉爽");
        //因为对于季节而已,他的对象(具体值),是固定的四个,不会有更多
        //安老师的这个设计类的思路,不能体现季节是固定的四个对象
        //因此,这样的设计不好===> 枚举类
        //[枚: 一个一个 举: 例举,即把具体的对象一个一个例举出来的类就称为枚举类]
    }
}
class Season//类
{
    private String name;
    private String desc;

    public Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

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

11.2 分析问题

11.2.1 创建 Season 对象有如下特点

1) 季节的值是有限的几个值(spring, summer, autumn, winter)

2) 只读,不需要修改。

11.3 解决方案-枚举

1) 枚举对应英文(enumeration, 简写 enum)

2) 枚举是一组常量的集合。

3) 可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。

11.4 枚举的二种实现方式

1) 自定义类实现枚举

2) 使用 enum 关键字实现枚举

11.5 自定义类实现枚举-应用案例

1.不需要提供set Xxx方法,因为枚举对象值通常为只读。
2.对枚举对象/属性使用static+final共同修饰,实现底层优化.
3.枚举对象名通常使用全部大写,常量的命名规范.
4.枚举对象根据需要,也可以有多个属性

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class Enumeration02
{
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
        System.out.println(Season.WINTER);
    }
}
class Season//类
{
    private String name;
    private String desc;

    //1. 将构造器私有化,目的防止直接 new
    //2. 去掉 setXxx 方法, 防止属性被修改
    //3. 在 Season 内部,直接创建固定的对象
    //4. 优化,可以加入 final 修饰符(调用final修饰的静态成员时,类不会被加载)

    //定义了四个对象, 加final可以固定(常量必须大写)
    public static final Season SPRING = new Season("春天","温暖");
    public static final Season WINTER = new Season("冬天", "寒冷");
    public static final Season AUTUMN = new Season("秋天", "凉爽");
    public static final Season SUMMER = new Season("夏天", "炎热");

    private Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

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

11.6 自定义类实现枚举-小结

11.6.1 小结

进行自定义类实现枚举,有如下特点:

1) 构造器私有化

2) 本类内部创建一组对象[四个 春夏秋冬]

3) 对外暴露对象(通过为对象添加 public final static 修饰符)

4) 可以提供 get 方法,但是不要提供 set(因为只读)

11.7 enum 关键字实现枚举-快速入门

11.7.1 说明

使用 enum 来实现前面的枚举案例,看老师演示,主要体会和自定义类实现枚举不同的地方。

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class Enumeration03
{
    public static void main(String[] args) {
        System.out.println(Season02.SPRING);
    }
}
//演示使用 enum 关键字来实现枚举类
enum Season02//类
{

    //定义了四个对象, 加final可以固定(常量必须大写)
//    public static final Season02 SPRING = new Season02("春天","温暖");
//    public static final Season02 WINTER = new Season02("冬天", "寒冷");
//    public static final Season02 AUTUMN = new Season02("秋天", "凉爽");
//    public static final Season02 SUMMER = new Season02("夏天", "炎热");

    //如果使用了 enum 来实现枚举类
    //1. 使用关键字 enum 替代 class
    //2. public static final Season SPRING = new Season("春天", "温暖") 要改成
    // SPRING("春天", "温暖") 解读 常量名(实参列表)
    //3. 如果有多个常量(对象), 使用 ,号间隔即可
    //4. 如果使用 enum 来实现枚举,要求将定义常量对象,写在前面
    //5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 ()

    SPRING("春天","温暖"),WINNER("冬天", "寒冷"),
    AUTUMN("秋天", "凉爽"),SUMMER("夏天", "炎热");
    private String name;
    private String desc;

    private Season02(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

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

11.7.2 enum 关键字实现枚举注意事项

1) 当我们使用 enum 关键字开发一个枚举类时,默认会继承 Enum 类, 而且是一个 final 类[如何证明],使用 javap 工具来演示

在这里插入图片描述

在这里插入图片描述

2) 传统的 public static final Season2 SPRING = new Season2(“春天”, “温暖”); 简化成 SPRING(“春天”, “温暖”), 这里必 须知道,它调用的是哪个构造器.

3) 如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略

4) 当有多个枚举对象时,使用 , 间隔,最后有一个分号结尾

5) 枚举对象必须放在枚举类的行首.

11.8 enum 关键字实现枚举-课堂练习

下面代码是否正确, 并说明表示的含义?

enum Gender

{

​ BOY , GIRL; //这里其实就是调用 Gender 类的无参构造器

}

  1. 上面语法是 ok

  2. 有一个枚举类 Gender, 没有属性。

  3. 有两个枚举对象 BOY, GIRL, 使用的无参构造器创建.

下面代码输出什么? EnumExercise01.java

在这里插入图片描述

11.9 enum 常 2 用方法说明

说明:使用关键字 enum 时,会隐式继承 Enum 类, 这样我们就可以使用 Enum 类相关的方法。[看下源码定义.]

public abstract class Enum<E extends Enum<E>>

implements Comparable<E>, Serializable {

 }

enum常用方法一览表

在这里插入图片描述

11.10 enum 常用方法应用实例

我们一起来举例说明 enum 常用的方法的使用,对 Season2 测试. EnumMethod.java

1) toString:Enum 类已经重写过了,返回的是当前对象 名,子类可以重写该方法,用于返回对象的属性信息

2) name:返回当前对象名(常量名),子类中不能重写

3) ordinal:返回当前对象的位置号,默认从 0 开始

4) values:返回当前枚举类中所有的常量

5) valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!

6) compareTo:比较两个枚举常量,比较的就是编号!

  1. 代码
package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class EnumMethod
{
    public static void main(String[] args) {
        //使用 Season2 枚举类,来演示各种方法
        Season02 autumn = Season02.AUTUMN;
        //输出枚举对象的名字
        System.out.println(autumn.name());
        //ordinal() 输出的是该枚举对象的次序/编号,从 0 开始编
        //AUTUMN 枚举对象是第三个,因此输出 2
        System.out.println(autumn.ordinal());
//从反编译可以看出 values 方法,返回 Season2[]
//含有定义的所有枚举对象
        Season02[] values = Season02.values();
        System.out.println("===遍历取出枚举对象(增强 for)====");
        for (Season02 season: values) {//增强 for 循环
            System.out.println(season);
        }
        //valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常
        //执行流程
        //1. 根据你输入的 "AUTUMN" 到 Season2 的枚举对象去查找
        //2. 如果找到了,就返回,如果没有找到,就报错
        Season02 autumn1 = Season02.valueOf("AUTUMN");
        System.out.println("autumn1=" + autumn1);
        System.out.println(autumn == autumn1);
            //compareTo:比较两个枚举常量,比较的就是编号
            //老韩解读
            //1. 就是把 Season2.AUTUMN 枚举对象的编号 和 Season2.SUMMER 枚举对象的编号比较
            //2. 看看结果
            /*
    public final int compareTo(E o) {

        }
    }
    return self.ordinal - other.ordinal;
    }
    Season2.AUTUMN 的编号[2] - Season2.SUMMER 的编号[3]
    */
        System.out.println(Season02.AUTUMN.compareTo(Season02.SUMMER));
        //补充了一个增强 for
        // int[] nums = {1, 2, 9};
        // //普通的 for 循环
        // System.out.println("=====普通的 for=====");
        // for (int i = 0; i < nums.length; i++) {
        // System.out.println(nums[i]);
        // }
        // System.out.println("=====增强的 for=====");
        // //执行流程是 依次从 nums 数组中取出数据,赋给 i, 如果取出完毕,则退出 for
        // for(int i : nums) {
        // System.out.println("i=" + i);
        // }
    }
}

课堂完成 :

声明 Week 枚举类,其中包含星期一至星期日的定义; MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; 使用 values 返回所有的枚举数组, 并遍历

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class EnumExercise02
{
    public static void main(String[] args) {
        //获取到所有的枚举对象,即数组
        Week[] weeks = Week.values();
        //遍历,使用增强for
        System.out.println("===所有星期的信息如下===");
        for(Week week :weeks)//增强for
        {
            System.out.println(week);
        }

    }
}
enum Week
{
    //定义Week的枚举对象
    MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),
    THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),
    SUNDAY("星期日");
    private String name;

    Week(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return  name;
    }
}

11.11 enum 实现接口

1) 使用 enum 关键字后,就不能再继承其它类了,因为 enum 会隐式继承 Enum,而 Java 是单继承机制。

**2) 枚举类和普通类一样,可以实现接口,如下形式。 **

enum 类名 implements 接口 1,接口 2{}
  1. 代码
package SeniorJava.Enumeration;
/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class EnumDetail {
public static void main(String[] args) {
Music.CLASSICMUSIC.playing();
}
}
class A {
}
//1.使用 enum 关键字后,就不能再继承其它类了,因为 enum 会隐式继承 Enum,而 Java 是单继承机制
//enum Season3 extends A {
//
//}
//2.enum 实现的枚举类,仍然是一个类,所以还是可以实现接口的. interface IPlaying {
public void playing();
}
enum Music implements IPlaying 
{
    CLASSICMUSIC;
    @Override
    public void playing() 
	{
    System.out.println("播放好听的音乐...");
	}
}

11.12 注解的理解

1) 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。

2) 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。

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

11.13 基本的 Annotation 介绍

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用。

用于修饰它支持的程序元素 三个基本的 Annotation:

1) @Override: 限定某个方法,是重写父类方法, 该注解只能用于方法

2) @Deprecated: 用于表示某个程序元素(类, 方法等)已过时

3) @SuppressWarnings: 抑制编译器警告

11.14 基本的 Annotation 应用案例

11.14.1 @Override 注解的案例

在这里插入图片描述

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class Override_
{
    public static void main(String[] args) {

    }
}
class Father{//父类
    public void fly(){
        System.out.println("Father fly...");
    }
    public void say(){}
}
class Son extends Father {//子类
    //老韩解读
//1. @Override 注解放在 fly 方法上,表示子类的 fly 方法时重写了父类的 fly
//2. 这里如果没有写 @Override 还是重写了父类 fly
//3. 如果你写了@Override 注解,编译器就会去检查该方法是否真的重写了父类的
//方法,如果的确重写了,则编译通过,如果没有构成重写,则编译错误
//4. 看看 @Override 的定义
//解读:如果发现 @interface 表示一个 注解类
/*
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
*/
    @Override //说明
    public void fly() {
        System.out.println("Son fly....");
    }
    @Override
    public void say() {}
}

Override使用说明(小结)
1.@Override表示指定重写父类的方法(从编译层面验证),如果父类没有fly方法,则会报错
2.如果不写@Override注解,而父类仍有public void fly00,仍然构成重写
3.@Override只能修饰方法,不能修饰其它类,包,属性等等
4.查看@Override注解源码为@Target(Element Type.METHOD),说明只能修饰方法
5.@Target是修饰注解的注解,称为元注解,记住这个概念。

11.14.2 @Deprecated 注解的案例

@Deprecated: 用于表示某个程序元素(类, 方法等)已过时

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class Deprecated_
{
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.n1);
        a.hi();
    }
}
//解读
//1. @Deprecated 修饰某个元素, 表示该元素已经过时
//2. 即不在推荐使用,但是仍然可以使用
//3. 查看 @Deprecated 注解类的源码
//4. 可以修饰方法,类,字段, 包, 参数 等等
//5. @Deprecated 可以做版本升级过渡使用
@Deprecated
class A
{

    @Deprecated
    public int n1 = 10;
    @Deprecated
    public void hi()
    {
        System.out.println("hi!");
    }
}

@Deprecated的说明
1.用于表示某个程序元素(类,方法等)已过时
2.可以修饰方法,类,字段,包,参数等等
3.@Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,
PACKAGE,PARAMETER,TYPE))
4.@Deprecated的作用可以做到新旧版本的兼容和过渡

11.14.3 @SuppressWarnings 注解的案例

@SuppressWarnings: 抑制编译器警告

package SeniorJava.Enumeration;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */

public class SuppressWarnings_
{
    //解读
    //1. 当我们不希望看到这些警告的时候,可以使用 SuppressWarnings 注解来抑制警告信息
    //2. 在{""} 中,可以写入你希望抑制(不显示)警告信息
    //3. 可以指定的警告类型有
    // all,抑制所有警告
    // boxing,抑制与封装/拆装作业相关的警告
    // //cast,抑制与强制转型作业相关的警告
    // //dep-ann,抑制与淘汰注释相关的警告
    // //deprecation,抑制与淘汰的相关警告
    // //fallthrough,抑制与 switch 陈述式中遗漏 break 相关的警告
    // //finally,抑制与未传回 finally 区块相关的警告
    // //hiding,抑制与隐藏变数的区域变数相关的警告
    // //incomplete-switch,抑制与 switch 陈述式(enum case)中遗漏项目相关的警告
    // //javadoc,抑制与 javadoc 相关的警告
    // //nls,抑制与非 nls 字串文字相关的警告
    // //null,抑制与空值分析相关的警告
    // //rawtypes,抑制与使用 raw 类型相关的警告
    // //resource,抑制与使用 Closeable 类型的资源相关的警告
    // //restriction,抑制与使用不建议或禁止参照相关的警告
    // //serial,抑制与可序列化的类别遗漏 serialVersionUID 栏位相关的警告
    // //static-access,抑制与静态存取不正确相关的警告
    // //static-method,抑制与可能宣告为 static 的方法相关的警告
    // //super,抑制与置换方法相关但不含 super 呼叫的警告
    // //synthetic-access,抑制与内部类别的存取未最佳化相关的警告
    // //sync-override,抑制因为置换同步方法而遗漏同步化的警告
    // //unchecked,抑制与未检查的作业相关的警告
    // //unqualified-field-access,抑制与栏位存取不合格相关的警告
    // //unused,抑制与未用的程式码及停用的程式码相关的警告
    //4. 关于 SuppressWarnings 作用范围是和你放置的位置相关
    // 比如 @SuppressWarnings 放置在 main 方法,那么抑制警告的范围就是 main
    // 通常我们可以放置具体的语句, 方法, 类

    @SuppressWarnings({"all"})
    public static void main(String[] args) {
            List list = new ArrayList();
            list.add("jack");
            list.add("tom");
            list.add("mary");
            int i;
            System.out.println(list.get(1));
    }
}

@SuppressWarnings注解的案例
说明各种值
1)unchecked是忽略没有检查的警告
2)raw types是忽略没有指定泛型的警告(传参时没有指定泛型的警告错误)
3)unused是忽略没有使用某个变量的警告错误
4)@Suppress Warnings可以修饰的程序元素为,查看@Target,
5)生成@Suppers s Warnings时,不用背,直接点击左侧的黄色提示,就
可以选择(注意可以指定生成的位置)

11.15 JDK 的元 Annotation(元注解, 了解)

11.15.1 元注解的基本介绍

JDK 的元 Annotation 用于修饰其他 Annotation

11.15.2 元注解的种类 (使用不多,了解, 不用深入研究)

1) Retention //指定注解的作用范围,三种 SOURCE,CLASS,RUNTIME

2) Target // 指定注解可以在哪些地方使用

3) Documented //指定该注解是否会在 javadoc 体现

4) Inherited //子类会继承父类注解

11.15.3 @Retention 注解

说明 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 @Rentention 时必须为该 value 成员变量指定值:

@Retention 的三种值

1) RetentionPolicy.SOURCE: 编译器使用后,直接丢弃这种策略的注释

2) RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解。 这是默认值

3) RetentionPolicy.RUNTIME:编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以 通过反射获取该注解

在这里插入图片描述

11.15.4 @Target

在这里插入图片描述

11.15.5 @Documented

在这里插入图片描述

在这里插入图片描述

11.15.6 @Inherited 注解

被它修饰的Annotation将具有继承性.如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解

说明:实际应用中,使用较少,了解即可。

元注解:本身作用不大,讲这个原因希望同学们,看源码时,可以知道他是干什么。

11.16 第 10 章作业

第一题:

1.在Frock类中声明私有的静态属性current Num[in t类型],初始值为100000,作为衣服出厂的序列号起始值。
2.声明公有的静态方法get Next Num,作为生成上衣唯一序列号的方法。每调用一次,将current Num增加100,并作为返回值。
3.在Test Frock类的main方法中,分两次调用get Next Num方法,获取序列号并打印输出。
4.在Frock类中声明serial Number(序列号)属性,并提供对应的get方法:
5.在Frock类的构造器中,通过调用get Next Num方法为Frock对象获取唯一序列号,赋给serial Number属性。
6.在Test Frock类的main方法中,分别创建三个Frock对象,并打印三个对象的序列号,验证是否为按100递增。

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class HomeWork01
{
}
class Frock
{
    private static int currentNum = 100000;
    private int serialNumber;

    public Frock()
    {
        serialNumber = getNextNum();
    }

    public static int getNextNum()
    {
        currentNum += 100;
        return currentNum;
    }

    public int getSerialNumber() {
        return serialNumber;
    }
}
class TestFrock
{
    public static void main(String[] args) {
        System.out.println(Frock.getNextNum());
        System.out.println(Frock.getNextNum());
        Frock frock = new Frock();
        Frock frock1 = new Frock();
        Frock frock2 = new Frock();
        System.out.println(frock.getSerialNumber());
        System.out.println(frock1.getSerialNumber());
        System.out.println(frock2.getSerialNumber());
    }
}

第二题:

按要求实现下列问题:抽象类的使用
1.动物类Animal包含了抽象方法shout().
2.Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫"
3.Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫”
4.在测试类中实例化对象Animal cat=new Cat(),并调用cat的shout方法
5.在测试类中实例化对象Animal dog=new Dog(),并调用dog的shout方法

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class HomeWork02
{
    public static void main(String[] args) {
        Animal cat = new Cat();
        Animal dog = new Dog();
        cat.shout();
        dog.shout();
    }
}
//1.动物类Animal包含了抽象方法shout().
//2.Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫"
//3.Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫”
//4.在测试类中实例化对象Animal cat=new Cat(),并调用cat的shout方法
//5.在测试类中实例化对象Animal dog=new Dog(),并调用dog的shout方法
abstract class Animal
{
    public abstract void shout();
}
class Cat extends Animal
{
    @Override
    public void shout() {
        System.out.println("猫会喵喵叫");
    }
}
class Dog extends Animal
{
    @Override
    public void shout() {
        System.out.println("狗会汪汪叫");
    }
}

第三题:

//考察对匿名内部类的使用
1.计算器接口具有work方法,功能是运算,有一个手机类Cellphone,定义方法test Work,测试计算功能,调用计算接口的work方法,

2.要求调用CellPhone对象的test Work方法,使用上匿名内部类

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class HomeWork03
{
    public static void main(String[] args) {
        Cellphone cellphone = new Cellphone();
        cellphone.testWork(new ICalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1+n2;
            }
        },10,8);
    }
}
//1.计算器接口具有work方法,功能是运算,有一个手机类Cellphone,
//定义方法test Work,测试计算功能,调用计算接口的work方法,
//2.要求调用CellPhone对象的test Work方法,使用上匿名内部类
interface ICalculate
{
    public double work(double n1 , double n2);
}
class Cellphone
{
    public void testWork(ICalculate iCalculate,double n1,double n2)
    {
        double result = iCalculate.work(n1,n2);
        System.out.println("运算结果:"+result);
    }
}

Phone对象的test Work方法,使用上匿名内部类

package SeniorJava.Enumeration;

/**
 * @author Yardonヽ(✿ ゚ ▽ ゚)ノ
 * @version 1.0
 */
public class HomeWork03
{
    public static void main(String[] args) {
        Cellphone cellphone = new Cellphone();
        cellphone.testWork(new ICalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1+n2;
            }
        },10,8);
    }
}
//1.计算器接口具有work方法,功能是运算,有一个手机类Cellphone,
//定义方法test Work,测试计算功能,调用计算接口的work方法,
//2.要求调用CellPhone对象的test Work方法,使用上匿名内部类
interface ICalculate
{
    public double work(double n1 , double n2);
}
class Cellphone
{
    public void testWork(ICalculate iCalculate,double n1,double n2)
    {
        double result = iCalculate.work(n1,n2);
        System.out.println("运算结果:"+result);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果需要在 Java 中使用注解来实现枚举校验,可以利用注解处理器来实现。具体来说,我们可以定义一个注解 EnumValue,该注解用于标记需要进行枚举校验的字段或方法参数。然后,我们可以编写一个注解处理器 EnumValueProcessor,该处理器会在编译时扫描代码中的 EnumValue 注解,并生成对应的校验代码。示例代码如下: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface EnumValue { Class<? extends Enum<?>> value(); } import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.MirroredTypeException; import javax.tools.Diagnostic; import java.util.Set; public class EnumValueProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(EnumValue.class)) { if (element.getKind() == ElementKind.FIELD) { processField(element); } else if (element.getKind() == ElementKind.PARAMETER) { processParameter(element); } } return true; } private void processField(Element element) { try { Class<? extends Enum<?>> enumClass = element.getAnnotation(EnumValue.class).value(); String fieldName = element.getSimpleName().toString(); String enumName = enumClass.getSimpleName(); String code = String.format("if (%s != null && !%s.class.isEnumConstant(%s)) {throw new IllegalArgumentException(\"%s must be one of %s values\");}", fieldName, enumName, fieldName, fieldName, enumName); processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated code: " + code, element); } catch (MirroredTypeException ex) { // Do nothing } } private void processParameter(Element element) { try { Class<? extends Enum<?>> enumClass = element.getAnnotation(EnumValue.class).value(); String paramName = element.getSimpleName().toString(); String enumName = enumClass.getSimpleName(); String code = String.format("if (%s != null && !%s.class.isEnumConstant(%s)) {throw new IllegalArgumentException(\"%s must be one of %s values\");}", paramName, enumName, paramName, paramName, enumName); processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated code: " + code, element); } catch (MirroredTypeException ex) { // Do nothing } } } public enum Fruit { APPLE, BANANA, ORANGE } public class EnumValidationDemo { @EnumValue(Fruit.class) private String fruit; public void setFruit(@EnumValue(Fruit.class) String fruit) { this.fruit = fruit; } public static void main(String[] args) { EnumValidationDemo demo = new EnumValidationDemo(); demo.setFruit("APPLE"); } } ``` 在上面的代码中,我们首先定义了一个注解 EnumValue,该注解用于标记需要进行枚举校验的字段或方法参数。然后,我们编写了一个注解处理器 EnumValueProcessor,该处理器会在编译时扫描代码中的 EnumValue 注解,并根据注解所标记的字段或方法参数生成对应的校验代码。在 processField() 和 processParameter() 方法中,我们使用 Element.getAnnotation() 方法获取注解的信息,并利用 String.format() 方法生成对应的校验代码。生成的代码会通过 Messager.printMessage() 方法输出到控制台。最后,在 EnumValidationDemo 类中,我们使用 @EnumValue(Fruit.class) 注解来标记 fruit 字段和 setFruit() 方法的参数,表示需要进行 Fruit 枚举校验。运行程序后,可以看到生成的校验代码为: ```java if (fruit != null && !Fruit.class.isEnumConstant(fruit)) {throw new IllegalArgumentException("fruit must be one of Fruit values");} ``` 这段代码会在 setFruit() 方法中被调用,用于校验输入值是否为 Fruit 枚举类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放下华子我只抽RuiKe5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值