Java修炼之路——基础篇——枚举

枚举的用法
每个枚举变量其实都是枚举类的一个实例。

枚举与单例
各种模式的单例模式,包括枚举实现的单例

//懒汉模式
class SingletonA {private static SingletonA instance = new SingletonA();//保证不能通过new SingletonB的方式创建对象private SingletonA(){}public static SingletonA getInstance() {return instance;}
}//保证效率的懒加载
class SingletonB {private static SingletonB instance;private SingletonB(){}public static SingletonB getInstance() {if(instance == null) {synchronized (SingletonB.class) {if (instance == null) {instance = new SingletonB();}}}return instance;}
}//内部类懒汉模式
class SingletonC {private SingletonC(){}private static class SingletonHolder {private static final SingletonC instance = new SingletonC();}public SingletonC getInstance() {return SingletonHolder.instance;}
}//内部枚举类懒加载模式
class SingletonD {private SingletonD(){}private enum EnumSingleton {instance;//因为枚举变量是static final的,所以如果不是定义时声明,那只能在构造方法中实例化,并且有且只能实例化一次。//所以保证了resource对象的单例性。private SingletonD singletonD;private EnumSingleton() {singletonD = new SingletonD();}}public SingletonD getInstance() {return EnumSingleton.instance.singletonD;}
}

枚举如何比较
可以用equals(),也可以用==,推荐使用==
enum的equals()方法实现如下:

public final boolean equals(Object other) {return this==other;}

可以看出,也是调用的==实现的。
官方文档说明如下:

JLS 8.9 Enums 一个枚举类型除了定义的那些枚举常量外没有其他实例了。 试图明确地说明一种枚举类型是会导致编译期异常。
在枚举中final clone方法确保枚举常量从不会被克隆,而且序列化机制会确保从不会因为反序列化而创造复制的实例。
枚举类型的反射实例化也是被禁止的。
总之,以上内容确保了除了定义的枚举常量之外,没有枚举类型实例。

另外,==和equals()的不同如下:

== 不会抛出 NullPointerException
enum Color { BLACK, WHITE };Color nothing = null;
if (nothing == Color.BLACK);      // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException== 在编译期检测类型兼容性
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT);      // DOESN'T COMPILE!!! Incompatible types!

总而言之,在枚举比较上使用 == , 因为: 1. 能正常工作 2. 更快 3. 编译期是安全的 4. 运行时也是安全的

switch 对枚举的支持
枚举 switchcase 标签必须为枚举常量的非限定名称
用法如下:

//定义枚举
public enum Color {RED,GREEN,YELLOW;
}//使用枚举
public void compare(Color color) {switch (color) {case RED:break;case YELLOW:break;	default:break;}}

枚举的线程安全性问题
枚举的序列化如何实现
枚举是线程安全的,描述如下:

1:枚举的实现方式

//定义枚举
public enum t {SPRING,SUMMER,AUTUMN,WINTER;
}
//反编译枚举类
public final class T extends Enum
{private T(String s, int i){super(s, i);}public static T[] values(){T at[];int i;T at1[];System.arraycopy(at = ENUM$VALUES, 0, at1 = new T[i = at.length], 0, i);return at1;}public static T valueOf(String s){return (T)Enum.valueOf(demo/T, s);}public static final T SPRING;public static final T SUMMER;public static final T AUTUMN;public static final T WINTER;private static final T ENUM$VALUES[];static{SPRING = new T("SPRING", 0);SUMMER = new T("SUMMER", 1);AUTUMN = new T("AUTUMN", 2);WINTER = new T("WINTER", 3);ENUM$VALUES = (new T[] {SPRING, SUMMER, AUTUMN, WINTER});}
}

通过反编译后代码我们可以看到,public final class T extends Enum,说明,该类是继承了Enum类的,同时final关键字告诉我们,这个类也是不能被继承的。
并且方法与属性都是static的,而static类型的属性会在类被加载之后被初始化。当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的。

2:枚举的序列化
JavaDoc中的描述:

序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,
反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。
同时,编译器是不允许任何对这种序列化机制的定制的,
因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。 

我们看一下这个valueOf方法:

public static <T extends Enum<T>>T valueOf(Class<T> enumType,String name) {  T result = enumType.enumConstantDirectory().get(name);  if (result != null)  return result;  if (name == null)  throw new NullPointerException("Name is null");  throw new IllegalArgumentException(  "No enum const " + enumType +"." + name);  }

从代码中可以看到,代码会尝试从调用enumType这个Class对象的enumConstantDirectory()方法返回的map中获取名字为name的枚举对象,如果不存在就会抛出异常。再进一步跟到enumConstantDirectory()方法,就会发现到最后会以反射的方式调用enumType这个类型的values()静态方法,也就是上面我们看到的编译器为我们创建的那个方法,然后用返回结果填充enumType这个Class对象中的enumConstantDirectory属性。

所以,JVM对序列化有保证。
此段描述来自于:http://blog.jobbole.com/94074/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker(二)-在Docker中部署Nginx实现负载均衡【完整教程】

一、前言【查看完整视频教程&#xff08;免费&#xff09;&#xff0c;请拉直文尾】在前面的文章中我们已经介绍了如何在Centos7系统中安装Docker以及利用Docker进行Asp.Net Core应用的部署。在本文中&#xff0c;我们将继续介绍利用Docker部署Nginx服务实现负载均衡。文章最后…

HDU 6127 Hard challenge(极角 + 二分)

Hard challenge 思路 通过极角排序&#xff0c;这里通过修改后&#xff0c;所有点的角度在[0,2π)[0, 2 \pi)[0,2π)之间&#xff0c; 然后O(n)O(n)O(n)扫一趟&#xff0c;对当前在的级角加上π\piπ就是我们要找的角度了&#xff0c;这里通过二分来实现查找。 接下来就只要…

P2664 树上游戏(点分治/计数题计算贡献/树上差分)

P2664 树上游戏 对于树上n个点&#xff0c;每个点有不同颜色&#xff0c;求解每个点到其他点的路径上不同颜色个数之和。 首先看到这种树上点对问题&#xff0c;我们可以想到点分治&#xff0c;然后考虑每次分治如何求解答案&#xff0c;本质上就是一个数颜色的问题&#xff…

2019-03-4-算法-进化(罗马数字转整数)

题目描述 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000例如…

设置ABP默认使用中文

ABP提供的启动模板, 默认使用是英文:虽然可以通过右上角的菜单切换成中文, 但是对于国内项目来说, 默认使用中文是很正常的需求.前期准备使用ABP CLI创建一个名为AbpStudy的ASP.NET MVC项目:abp new AbpStudy关于MVC的启动模板可以看文档, 这里就不赘述.使用ABP版本的是当前最新…

P3835 【模板】可持久化平衡树

P3835 【模板】可持久化平衡树 好久没有打平衡树了&#xff0c;赶紧来复习一下&#xff0c;平衡树这种东西还是很有用的&#xff0c;可以很灵活地解决一些问题。 fhq_treap 这道题是可持久化的权值平衡树&#xff0c;支持以下几个操作 1、 插入 xxx 2、 删除 xxx&#xff08…

基础篇--Java IO--概览

字符流、字节流、输入流、输出流 Java 中使用IO&#xff08;输入输出&#xff09;来读取和写入&#xff0c;读写磁盘文件、内存、网络数据。输入输出是相对内存而言&#xff0c;往内存中读数据就为输入流&#xff0c;从内存中往外写就是输出流。 根据处理类型分为字符流、字节…

半平面交练习(计算几何)

四&#xff1a;半平面交 Rotating Scoreboard /*Author : lifehappy */ #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <iostream>using namespace std;const double pi ac…

.NET轻松写博客园爬虫

爬虫&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网站的程序或者脚本。.NET写爬虫非常简单&#xff0c;并能轻松优化性能。今天我将分享一段简短的代码&#xff0c;爬出博客园前200页精华内容&#xff0c;然后通过微小的改动&#xff0c;将代码升级为多线程爬虫&am…

P5055 【模板】可持久化文艺平衡树

P5055 【模板】可持久化文艺平衡树 突然发现fhq_treap也是可以支持区间翻转的&#xff0c;所以基本上和其他平衡树是一样的&#xff0c;而且还满足重量平衡树的性质&#xff0c;真是太优秀了&#xff0c;只不过常数稍微比较大。 然后这里我们变成了一颗区间平衡树&#xff0c…

kettle同步数据中文乱码问题解决

最近在使用kettle进行数据同步的时候&#xff0c;发现同步来的中文数据产生了乱码。试了下网上的解决方案&#xff0c;最终解决了这个问题。步骤如下&#xff1a; 1&#xff1a;kettle中配置源数据库、目标数据库编码 2&#xff1a;编辑“表输入”&#xff0c;去掉勾选“允许建…

WTM重磅更新,LayuiAdmin免费用 and more

从善如登&#xff0c;从恶如崩。对于一个开发人员来说&#xff0c;那就是做一个好的系统不容易&#xff0c;想搞砸一个系统很简单&#xff0c;删库跑路会还不会么。对于我们开源框架的作者来说&#xff0c;做一个好的框架就像登山&#xff08;也许是登天&#xff09;&#xff0…

Lady Layton with Math(杜教筛)

Lady Layton with Math ∑i1n∑j1nϕ(gcd(i,j))∑d1nϕ(d)∑i1n∑j1n[gcd(i,j)d]∑d1nϕ(d)∑i1nd∑j1nd[gcd(i,j)1]∑d1nϕ(d)(2∑i1nd∑j1i[gcd(i,j)1]−1)∑d1nϕ(d)(2∑i1ndϕ(i)−1)\sum_{i 1} ^{n} \sum_{j 1} ^{n} \phi(gcd(i, j))\\ \sum_{d 1} ^{n} \phi(d) \sum_{…

概率期望复习

概率期望 P(A并B)P(A)P(B)-P(A交B) 条件概率 已知A发生B发生的概率&#xff0c;记作P(B|A) 四种情况 P(AB都发生)a,P(AB都不发生)b P(只有A发生)c,P(只有B发生)d P(B|A)a/(ac),即P(B|A)P(AB)/P(A) 全概率公式 P(A)P(B1)P(A|B1)…P(Bn)P(A|Bn) 三门问题 生日悖论 贝叶斯…

kettle数据库操作OPTION SQL_SELECT_LIMIT=DEFAULT问题解决

今天在使用kettle配置数据库映射的时候&#xff0c;有如下报错&#xff1a; Couldnt get field info from [select * from pre_user_base_bak]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax …

.netcore 分布式事务CAP2.6 快速入门

CAP介绍&#xff1a;CAP是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案。可以解决跨服务器的数据一致性问题。一个简单的列子&#xff0c;如&#xff1a;订单系统创建订单后需要通知邮件通知用户下单成功&#xff0c;解决方案有下面几种&#xff1…

[SDOI2017]数字表格

[SDOI2017]数字表格 假定n<m∏i1n∏j1mf(gcd(i,j))∏d1nf(d)∑i1n∑j1m[gcd(i,j)d]∏d1nf(d)∑i1nd∑j1md[gcd(i,j)1]∏d1nf(d)∑k1ndμ(k)nkdmkd由于nd具有分块性质&#xff0c;并且n&#xff0c;m不大&#xff0c;所以我们可以先预处理出斐波那契数列的前缀积&#xff0c;…

#3601. 一个人的数论

#3601. 一个人的数论 首先这个转化还是很巧妙的&#xff0c;或者很套路的&#xff0c;直接莫比乌斯反演&#xff0c;然后看到了自然数幂之和的形式&#xff0c;那么我们就可以转化为多项式处理&#xff0c;项数就减少到了d1&#xff0c;然后看到题目给出的都是质因数分解结果&a…

2019-03-5-算法-进化(最长公共前缀)

题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1: 输入: ["flower","flow","flight"] 输出: "fl"示例 2: 输入: ["dog","racecar","…

基于SQLite+EF6实现一套自己的Key-Value存储管理工具包(2)

上一篇里面整理了一下需求和思路&#xff0c;自定义了扩展的字典对象&#xff0c;这里我们再继续深入编码。BaseExtensions类&#xff0c;这个类作未来任何需要Key-Value形式扩展的基类1234567891011121314151617181920212223242526272829303132333435363738394041424344454647…