【Java学习】枚举(匿名类详解)

目录

一、匿名类

1.形式

2.性质

2.1匿名性

2.1.1同步性

使用场景

2.1.2复用性

2.1.3向上转型

2.2实现性

3.传参

3.1构造传全参

3.1.1过程

3.1.2效果

2.1.4原子类构造无参

4.权限

二、枚举类

1.枚举常量

2.性质

2.1多态性

2.2单例性

2.2.1private保护

2.2.2final保护

2.3final修饰

2.3.1类保护

2.3.1.1常量性

2.3.1.2单例特性

枚举类内部匿名的豁免

2.3.2方法限制

2.3.3变量要求

2.3.3.1非静态成员

2.3.3.2静态成员

3.结构

3.1二次继承

3.2代码省略

原版代码

4.方法使用

4.1获取

4.1.1获取枚举常量

4.1.1.1获取一个枚举常量:

4.1.1.2获取所有枚举常量:

4.1.2获取枚举常量序号:

4.2比较:


一、匿名类

匿名子类,继承于父类,是用 父类 与 原子类纯内容{} ++直接拼接继承合成++ 的 子类 ,存在于new结构中的 方法内部中的,都是 继承扩展的 ++子类++ 、++内部类++


1.形式

匿名子类的创建结构为 new 父类构造方法(构造全参) {原子类扩展内容};


2.性质

2.1匿名性

2.1.1同步性

只有在new实例化时 才同步允许这种 拼接继承合成的 匿名子类 ,所以**++匿名子类的拼接继承创建++** 与**++匿名子类的实例化++** 是创建后紧接着立马实例化使用 同步进行 的,如果匿名子类 创建了 不立即去使用的,++到后面再使用的话 都没名字的 根本无法使用到它++:

使用场景

适用于 只用一次 不复用 立马临时创建出 多态下 去应付针此情况下的 此态子类的 实例对象快速实现接口 或 继承抽象类 直接只为应付此时情况的 去一次性创建对象


2.1.2复用性

++原子类++ 只有内容 ++没有类名++ ,父类与原子类继承合成的 ++匿名子类 也就没有类名++ ,++直接用拼接表示的++ ,匿名类没有名字,无法代指,类结构一样的 匿名类的表示 都得从头重新表示起不能代指 表示复用,代码复用性差


2.1.3向上转型

创建出的匿名子类 无类名的,无法用它匿名类 创建实例引用来接收 ,只能用 有类名的父类 来创建实例引用 接收,即匿名子类实例化对象 创建出来后 用它的父类 向上转型来接 来使用


2.2实现性

匿名子类 原子类的 扩展部分 因为外面即将对匿名子类 整体实例化new了扩展部分 必须扩展使 匿名子类继承后是实现类,如果父类那边是抽象下来的,匿名子类这边 就不能继续抽象继承下去,++必须立马实现掉所有抽象方法,继承为实现类++ 从而进行实例化


3.传参

3.1构造传全参

因为 子类是 原子类与上面所有父类的 整体任何一个子类 构造方法的传参 都是为 原子类与为上面全父类 一次全传好的 ,原子类与所有父类的构造方法的传参 所有都要顾及到的****往上传


3.1.1过程

原子类这边 接到所有类的 构造参数原子类对应的参数 它构造使用 后,将剩余的参数 接着往它的 直接父类传,剩余参数中 直接父类对应使用了 它构造方法的参数后 又把再剩下的 往它的父类 全再传


3.1.2效果

从原子类传的 全参数 到此层 此层的构造使用完后 接着再为上层 所有父类 剩余地 全传,传的全参 在一次次到达所对应的父类构造器使用后 每次传的全参 也就慢慢地减少


2.1.4原子类构造无参

匿名子类的原子类 没有名字 没构造方法的,所以 匿名子类构造 传的参 全是它上面父类部分的 ,传的参数为 直接父类++枚举类Operation构造方法的一个String字符串++ 与再上层++父类Enum的一个String字符串与一个int整数++


4.权限

匿名类内部 只能访问外部final常量或等效final的变量


二、枚举类

1.枚举常量

枚举常量即枚举对象,是枚举类的 匿名子类的 实例化对象 ,在枚举类加载完 就++立马实例化++ 匿名子类 ,将枚举对象 也**++静态加载++ 存储在 枚举类变量中静态存储** ,作为final静态实例 在类加载初始化后 就不可变的


2.性质

2.1**多态性**

每一个枚举对象 可不同子类地扩展 成不同的匿名子类 来实例化创建出 多态的枚举对象


2.2单例性

枚举类的 所有匿名子类 只有的是 枚举类自身里面创建时 自创的每一个枚举常量都是 只由只能在枚举类里面创建的 (虽然不同的枚举类里面 可以创建相同父类成员String 即相同名字的 枚举常量对象,但因为 它们在不同的类中定义的,++枚举对象的访问 是先通过枚举类变量 来静态访问的,最前面的枚举类不同 就会有区别 不同的++)


2.2.1private保护

在类外,枚举类的构造方法 是被private修饰的 ,在类外 无法使用构造方法 new实例化 枚举常量


2.2.2final保护

枚举类 是固定被final修饰的,所以就算 用反射 获取枚举类的构造器 再配合子类扩展部分 来实例化new 时,是先有匿名子类 才有实例化它 出匿名子类的实例对象 的,由于枚举类 始终是final修饰的 就是不可被继承的,不可被继承出有子类 包括new时拼接继承合成的 匿名子类的 ,再加上用反射 获取枚举类的构造器 也是被禁止的


2.3final修饰

2.3.1类保护

枚举类固定被final修饰,表示类不会被继承,就不可能有子类

2.3.1.1常量性

不可能出现有 发生向上转型的枚举类 通过在下面类外 重写修改 使枚举类固定常量性的方法 发生改变 ,保护了枚举对象的 常量固定性


2.3.1.2单例特性

阻止了 反射 在类外 多例地 再创建枚举常量 ,保护了枚举的单例特性


枚举类内部匿名的豁免

为什么枚举类被final修饰 但在内部 可以继承它 创建出它的匿名子类,从而创建有枚举对象?

因为枚举类里面的匿名子类 是编译器通过 直接生成 枚举类子类 字节码来创建的绕过了 final对不可创建子类的 检查限制 ,使得枚举类的匿名子类 可以发生,++枚举常量 得以具有多态性++


2.3.2方法限制

枚举方法如果被final修饰,表示 方法不会被覆盖重写 ,但枚举类层面 就已经固定被final修饰的 已确保了不会有继承 方法不会被重写方法去用final修饰 只会限制枚举常量的 重写多态性


2.3.3变量要求

变量如果被final修饰,表示变量里存储的值 不会改变,即变为常量

枚举常量引用变量 固定被final修饰的,表示引用里 存储的地址 不会改变,即引用的指向 不会改变 ,但枚举常量引用 指向的内容 即枚举类变量里面的 其它++成员变量 如果不用final修饰 就可以改变,就会破坏枚举常量 对应值的 常量对应性 而破坏常量的语义++ ,所以 其它成员变量 必须手动加有final修饰,加上后:

2.3.3.1非静态成员

枚举常量创建时 每次对非静态常量 实例化创建的 每次的复制变量 值对应赋上后枚举对象 就是 固定指向 复制常量成员里的 常量值


2.3.3.2静态成员

final修饰的 静态常量 属于类层面的 一次创建赋上 的,枚举对象 固定指向 静态常量成员里的常量值


3.结构

java 复制代码
enum Operation {//枚举类 Operation
    ADD("示例-枚举类Operation的 构造传参String") {//ADD 是静态存储的枚举常量,匿名子类的实例对象引用
//匿名子类的原子类层 没有构造方法,它的构造方法传参 固定只传的是 上面父类构造的参数,即枚举类变量的构造参数、Enum类的构造参数(省略了已由编译器完成的)
        public int apply(int a, int b) { return a + b; }//匿名子类的 原子类扩展部分,要求实现抽象方法 成为实现类
    },
    SUBTRACT("示例-枚举类Operation的 构造传参String"){//枚举常量 SUBTRACT
        public int apply(int a, int b) { return a - b; }
    };
    
    public final String ShiLi;//枚举类的 非静态成员变量

    Operation(String ShiLi) {//枚举类的 构造方法
        this.ShiLi = ShiLi;
    }

    public abstract int apply(int a, int b);//枚举类的 抽象方法,去实现了枚举常量的多态性
}

3.1二次继承

Enum类 往下继承出 枚举类枚举类 往下继承出 匿名子类 ,枚举常量 是Enum的子类枚举类 的子类匿名子类 二次继承下的实例对象


3.2代码省略

匿名子类的new 父类构造方法(构造全参) {原子类扩展内容};结构被大大地省略掉了:

只留了 实例化匿名子类 结果出的 枚举常量父类Enum传参被省略 只留了给父类枚举类 构造传的参匿名子类原子类的 {}扩展内容

原版代码
java 复制代码
abstract class Operation extends Enum<Operation> {//枚举类Operation继承Enum类
    //匿名子类实例引用即枚举常量ADD             匿名子类,继承枚举类Operation
    static final Operation ADD = new Operation("ADD", 0, "示例-枚举类的传参") {
      //Operation向上转型接收匿名子类实例      //匿名子类的原子类 没有构造方法,它的构造方法传参 传上面两个父类构造的参数
        public int apply(int a, int b) {
            return a + b;
        }
    };
    public final String ShiLi;
    Operation(String ShiLi) {//枚举类的 构造方法
        this.ShiLi = ShiLi;
    }
    public abstract int apply(int a, int b);//枚举类的 抽象方法
}

4.方法使用

4.1获取

4.1.1获取枚举常量
4.1.1.1获取一个枚举常量:

Operation.valueOf("枚举常量名");

---> return Operation

调用枚举类的静态方法,查找 在该枚举类中存储的 该字符串名称的枚举常量 并返回,枚举常量 在创建出来时 就已经直接向上转型的

4.1.1.2获取所有枚举常量:

Operation.values();

---> return Operation[]

调用枚举类的静态方法,将枚举类里面存储的 已向上转型的 枚举常量 以枚举类类型 数组 返回


4.1.2获取枚举常量序号:

Operation.ADD.ordinal();

---> return int

将此枚举常量的 父类序号成员 记录的 定义序号 返回


4.2比较:

Operation.ADD.compareTo(枚举常量);

---> return int

将此枚举常量 与另一个枚举常量 进行定义序号的 大小比较

相关推荐
cdut_suye3 分钟前
【Linux系统】从零开始构建简易 Shell:从输入处理到命令执行的深度剖析
java·linux·服务器·数据结构·c++·人工智能·python
-qOVOp-5 分钟前
zst-2001 历年真题 设计模式
java·算法·设计模式
大白的编程日记.26 分钟前
【Linux学习笔记】系统文件IO之重定向原理分析
linux·笔记·学习
张狂年少27 分钟前
【十五】Mybatis动态SQL实现原理
java·sql·mybatis
元亓亓亓1 小时前
Java后端开发day46--多线程(二)
java·开发语言
七七小报1 小时前
uniapp-商城-51-后台 商家信息(logo处理)
java·服务器·windows·uni-app
神奇小永哥1 小时前
浅谈装饰模式
java
jiunian_cn1 小时前
【c++】多态详解
java·开发语言·数据结构·c++·visual studio
喜欢便码1 小时前
python线上学习进度报告
学习
yousuotu1 小时前
python如何提取Chrome中的保存的网站登录用户名密码?
java·chrome·python