首页 > 解决方案 > 为什么枚举构造函数“this”和“Enum.this”不同

问题描述

我有一个本地枚举缓存,需要在枚举构造函数中返回枚举实例。但是当 return 'this' 失败时, return 'Enum.this' 就可以了。异常看起来像一个内部类。因为这个实例没有完成?这是我的代码和异常

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

在此处输入图像描述

在此处输入图像描述

标签: javaenums

解决方案


这里:

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方法位于匿名内部类new EnumGetter() { ... }中。这将创建一个这样的类。

// 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$1"
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. 所以在 of 内部get,非限定词this指的是 的当前实例SomeAnonymousClassName,而不是枚举的实例。

正如Java 语言规范所说:

当用作主要表达式时,关键字this表示一个值,该值是对调用实例方法或默认方法的对象或正在构造的对象的引用。

要引用枚举的当前实例,您必须使用TestEnum.this.


推荐阅读