java单例之enum实现方式(java enum 单例)

本文目录一览:

Java 中 Enum 如何继承?

Java Enum是不能继承的,以下是解释:

枚举类使用enum定义后在编译后默认继承了java.lang.Enum类,而不是普通的继承Object类。enum声明类继承了Serializable和Comparable两个接口。且采用enum声明后,该类会被编译器加上final声明(同String),故该类是无法继承的。枚举类的内部定义的枚举值就是该类的实例(且必须在第一行定义,当类初始化时,这些枚举值会被实例化)。

Java 5新增的enum关键词,可以定义枚举类。该类是一个特殊的类,可以定义自己的field、方法、可以实现接口,也可以定义自己的构造器。

在《Effective Java》中,为什么推荐使用enum来实现单例模式

单例模式实现方式有很多:在第一次使用的时候创建(构造函数中判断是否已经有实例存在),在类加载的时候用静态块儿创建(静态块初始化),在应用启动的时候创建。

在单线程中,基本大同小异,保证类的实例在整个应用中只有一个,都是没问题的。

但是在多线程环境下,什么时候创建这个实例是要考虑线程安全的。

枚举类型最大的特点就是:构造函数是private修饰的,也就是不能对其进行new,对象的实例都是预定义的,也就是在类加载的时候都是定义好了的,不会给其它调用去创建实例的机会。

结论是,可以模拟这个思路去创建单例,不一定非得用枚举,但是推荐用使用定义枚举的方式去实现单例模式

为什么java中用枚举实现单例模式会更好

单例模式实现方式有很多:在第一次使用的时候创建(构造函数中判断是否已经有实例存在),在类加载的时候用静态块儿创建(静态块初始化),在应用启动的时候创建。

在单线程中,基本大同小异,保证类的实例在整个应用中只有一个,都是没问题的。

但是在多线程环境下,什么时候创建这个实例是要考虑线程安全的。

枚举类型最大的特点就是:构造函数是private修饰的,也就是不能对其进行new,对象的实例都是预定义的,也就是在类加载的时候都是定义好了的,不会给其它调用去创建实例的机会。

结论是,可以模拟这个思路去创建单例,不一定非得用枚举,但是推荐用使用定义枚举的方式去实现单例模式

Java 枚举型为什么是静态的,以及是怎么实现的

是的,Java枚举型是静态常量,隐式地用static final修饰过。

确切地说,Java枚举型是“静态常量”,这里面包含了两层意思:

枚举型中的实例隐式地用static final修饰过。

枚举型作为某个类中的成员字段也隐式地用static final修饰过。

public class Traffic{

public enum Light{GREEN,YELLOW,RED}

}

还是你上面这个代码,反编译一下,你就能看到–编译器背着你偷偷做了哪些手脚:

/*

* Decompiled with CFR 0_118.

*/

package com.ciaoshen.thinkinjava.chapter19;

public class Traffic {

public static final class Light

extends EnumLight {

public static final /* enum */ Light GREEN = new Light();

public static final /* enum */ Light YELLOW = new Light();

public static final /* enum */ Light RED = new Light();

private static final /* synthetic */ Light[] $VALUES;

public static Light[] values() {

return (Light[])$VALUES.clone();

}

public static Light valueOf(String string) {

return Enum.valueOf(Light.class, string);

}

private Light() {

super(string, n);

}

static {

$VALUES = new Light[]{GREEN, YELLOW, RED};

}

}

}

首先,枚举型Light是个实实在在的类。继承自基类EnumLight。然后在你不知情的情况下,偷偷加了static final修饰词。

然后三个枚举实例GREEN, YELLOW, RED也确确实实是Light的实例。然而前面也加上了static final。

然后构造器也被偷偷地阉割成private。这种实例控制手段,是不是在单例器模式里也见过?所以枚举也是实现单例器的一种方法。

然后编译器还偷偷合成了Light[]数组,一个values( )方法,一个valueOf( )方法。这个values( )在Enum的文档里都找不到。

如果在Enum里定义一个相关方法,你还会看到一个匿名内部类:

public enum Light{

GREEN{public void show(){System.out.println(“Green”);}},

YELLOW{public void show(){System.out.println(“Yellow”);}},

RED{public void show(){System.out.println(“Red”);}};

}

反编译的结果如下:

/*

* Decompiled with CFR 0_118.

*/

package com.ciaoshen.thinkinjava.chapter18;

import java.io.PrintStream;

public class Light

extends EnumLight {

public static final /* enum */ Light GREEN = new Light(“GREEN”, 0){

public void show() {

System.out.println(“Green”);

}

};

public static final /* enum */ Light YELLOW = new Light(“YELLOW”, 1){

public void show() {

System.out.println(“Yellow”);

}

};

public static final /* enum */ Light RED = new Light(“RED”, 2){

public void show() {

System.out.println(“Red”);

}

};

private static final /* synthetic */ Light[] $VALUES;

public static Light[] values() {

return (Light[])$VALUES.clone();

}

public static Light valueOf(String string) {

return Enum.valueOf(Light.class, string);

}

private Light() {

super(string, n);

}

static {

$VALUES = new Light[]{GREEN, YELLOW, RED};

}

}

总之,Java的Enum枚举型整个就是一个大大的“语法糖”。明明是一个完整的类,但只向用户暴露几个静态常量,隐藏掉大部分实现的细节。

原创文章,作者:J33MY,如若转载,请注明出处:https://www.506064.com/n/127346.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
J33MY的头像J33MY
上一篇 2024-10-03 23:15
下一篇 2024-10-03 23:15

相关推荐

发表回复

登录后才能评论