为什么枚举构造函数 "this" 和 "Enum.this" 不同
Why enum constructor "this" and "Enum.this" is different
我有一个本地枚举缓存,需要在枚举构造函数中 return 枚举实例。但是当 return 'this' 时,它失败了, return 'Enum.this' 时,没关系。
异常看起来像一个内部 class。因为这个实例没有完成?
这是我的代码和例外
public static void main(String[] args) {
TestEnum testEnum = EnumManager.byK1(TestEnum.class,0);
}
public final class EnumManager {
private static final Map<Class,Map<String,Object>> K1_MAP = new HashMap<>(16);
private static final Map<Class,Map<String,Object>> K2_MAP = new HashMap<>(8);
private static final Map<Class,Map<String,Object>> K3_MAP = new HashMap<>(4);
public static void register(Class clazz, EnumGetter getter){
Map<String,Object> k1 = K1_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
Map<String,Object> k2 = K2_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
Map<String,Object> k3 = K3_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
if (Objects.nonNull(getter.getK1())){
k1.put(getter.getK1().toString(),getter.get());
}
if (Objects.nonNull(getter.getK2())){
k2.put(getter.getK2().toString(),getter.get());
}
if (Objects.nonNull(getter.getK3())){
k3.put(getter.getK3().toString(),getter.get());
}
}
public static <T> T byK1(Class clazz, Object k){
return by(K1_MAP,clazz,k.toString(),null);
}
public static <T> T byK1(Class clazz, Object k, T def){
return by(K1_MAP,clazz,k.toString(),def);
}
public static <T> T byK2(Class clazz, Object k){
return by(K2_MAP,clazz,k.toString(),null);
}
public static <T> T byK2(Class clazz, Object k,T def){
return by(K2_MAP,clazz,k.toString(),def);
}
public static <T> T byK3(Class clazz, Object k){
return by(K3_MAP,clazz,k.toString(),null);
}
public static <T> T byK3(Class clazz, Object k, T def){
return by(K3_MAP,clazz,k.toString(),def);
}
private static <T> T by(Map<Class,Map<String,Object>> map, Class clazz ,String key, T def){
Map<String,Object> m1 = map.get(clazz);
if (m1 == null){
clazz.getEnumConstants();
m1 = map.get(clazz);
}
if (m1 != null){
try {
return (T) m1.getOrDefault(key,def);
} catch (Exception e) {
log.error("conversion type error",e);
}
}
return def;
}
}
public enum TestEnum {
A_1(0, "A1");
private int code;
private String description;
private TestEnum(int code, String description) {
this.code = code;
this.description = description;
System.out.println(this.getClass());
System.out.println(this.getClass());
EnumManager.register(TestEnum.class, new EnumGetter() {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
});
}
public int getCode() {
return this.code;
}
public String getDescription() {
return this.description;
}
}
这里:
EnumManager.register(TestEnum.class, new EnumGetter() {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
});
请注意,get
方法位于匿名内部 class new EnumGetter() { ... }
中。这会创建一个像这样的 class。
// assuming EnumGetter is an interface
// this class doesn't actually have this name. As you can see from the error message,
// its name actually is "TestEnum"
class SomeAnonymousClassName implements EnumGetter {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
}
想象一下这段代码被放置在 TestEnum
中。所以在get
里面,非限定词this
指的是SomeAnonymousClassName
的当前实例,而不是枚举的实例。
正如 Java Language Specification 所说:
When used as a primary expression, the keyword this
denotes a value that is a reference to the object for which the instance method or default method was invoked, or to the object being constructed.
要引用枚举的当前实例,您必须使用 TestEnum.this
。
我有一个本地枚举缓存,需要在枚举构造函数中 return 枚举实例。但是当 return 'this' 时,它失败了, return 'Enum.this' 时,没关系。 异常看起来像一个内部 class。因为这个实例没有完成? 这是我的代码和例外
public static void main(String[] args) {
TestEnum testEnum = EnumManager.byK1(TestEnum.class,0);
}
public final class EnumManager {
private static final Map<Class,Map<String,Object>> K1_MAP = new HashMap<>(16);
private static final Map<Class,Map<String,Object>> K2_MAP = new HashMap<>(8);
private static final Map<Class,Map<String,Object>> K3_MAP = new HashMap<>(4);
public static void register(Class clazz, EnumGetter getter){
Map<String,Object> k1 = K1_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
Map<String,Object> k2 = K2_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
Map<String,Object> k3 = K3_MAP.computeIfAbsent(clazz,k -> new HashMap<>(4));
if (Objects.nonNull(getter.getK1())){
k1.put(getter.getK1().toString(),getter.get());
}
if (Objects.nonNull(getter.getK2())){
k2.put(getter.getK2().toString(),getter.get());
}
if (Objects.nonNull(getter.getK3())){
k3.put(getter.getK3().toString(),getter.get());
}
}
public static <T> T byK1(Class clazz, Object k){
return by(K1_MAP,clazz,k.toString(),null);
}
public static <T> T byK1(Class clazz, Object k, T def){
return by(K1_MAP,clazz,k.toString(),def);
}
public static <T> T byK2(Class clazz, Object k){
return by(K2_MAP,clazz,k.toString(),null);
}
public static <T> T byK2(Class clazz, Object k,T def){
return by(K2_MAP,clazz,k.toString(),def);
}
public static <T> T byK3(Class clazz, Object k){
return by(K3_MAP,clazz,k.toString(),null);
}
public static <T> T byK3(Class clazz, Object k, T def){
return by(K3_MAP,clazz,k.toString(),def);
}
private static <T> T by(Map<Class,Map<String,Object>> map, Class clazz ,String key, T def){
Map<String,Object> m1 = map.get(clazz);
if (m1 == null){
clazz.getEnumConstants();
m1 = map.get(clazz);
}
if (m1 != null){
try {
return (T) m1.getOrDefault(key,def);
} catch (Exception e) {
log.error("conversion type error",e);
}
}
return def;
}
}
public enum TestEnum {
A_1(0, "A1");
private int code;
private String description;
private TestEnum(int code, String description) {
this.code = code;
this.description = description;
System.out.println(this.getClass());
System.out.println(this.getClass());
EnumManager.register(TestEnum.class, new EnumGetter() {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
});
}
public int getCode() {
return this.code;
}
public String getDescription() {
return this.description;
}
}
这里:
EnumManager.register(TestEnum.class, new EnumGetter() {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
});
请注意,get
方法位于匿名内部 class new EnumGetter() { ... }
中。这会创建一个像这样的 class。
// assuming EnumGetter is an interface
// this class doesn't actually have this name. As you can see from the error message,
// its name actually is "TestEnum"
class SomeAnonymousClassName implements EnumGetter {
public Object get() {
return this;
}
public Object getK1() {
return code;
}
public Object getK2() {
return null;
}
public Object getK3() {
return null;
}
}
想象一下这段代码被放置在 TestEnum
中。所以在get
里面,非限定词this
指的是SomeAnonymousClassName
的当前实例,而不是枚举的实例。
正如 Java Language Specification 所说:
When used as a primary expression, the keyword
this
denotes a value that is a reference to the object for which the instance method or default method was invoked, or to the object being constructed.
要引用枚举的当前实例,您必须使用 TestEnum.this
。