Write generic static method in enum base class that can extract subclass instance to do a Jackson conversion

huangapple go评论73阅读模式
英文:

Write generic static method in enum base class that can extract subclass instance to do a Jackson conversion

问题

我有一些类似这样的枚举类型

    public static enum Thingie {
        ABC("abc"), DEF("def");
        
        private String messageValue;
        
        @JsonValue
        public String getMessageValue() { return messageValue; }
        
        private Thingie(String messageValue) { this.messageValue = messageValue; }
    }

这将允许 Jackson 正确地在字符串值和枚举类型之间进行编组和解组

可能会有时候我想直接将字符串值转换为枚举值这就像内部的 "fromValue()" 方法但不完全相同

    public static Thingie messageValueOf(String messageValue) {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.convertValue(messageValue, Thingie.class);
    }

我想将这个转换为一个通用方法并将其放入一个基类中同时还有 "messageValue" 属性和访问器构造方法将改为只调用 "super(messageValue)"显然如果可以的话我会将 "mapper" 移到类级别

到目前为止我只尝试将其编写为单个枚举类型中的通用方法我甚至无法让它工作我无法弄清楚如何从模板参数中提取类我之前见过这个特定的问题也有一些答案但我无法完全让它工作而且我想象在基类中尝试这样做会增加额外的复杂性
英文:

I have some enum types that look like this:

public static enum Thingie {
    ABC("abc"), DEF("def");
    
    private String  messageValue;
    
    @JsonValue
    public String getMessageValue() { return messageValue; }
    
    private Thingie(String messageValue) { this.messageValue = messageValue; }
}

This will allow Jackson to properly marshal and unmarshal between string values and the enum type.

There may be times when I'd like to directly convert a string value to the enum value. This would be like the internal "fromValue()" method, but not quite the same:

public static Thingie messageValueOf(String messageValue) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.convertValue(messageValue, Thingie.class);
}

I would like to convert this into a generic method AND put it into a base class, along with the "messageValue" property and accessor. The constructor would change to just call "super(messageValue)". Obviously, if I could do that, I would move the "mapper" to class level.

At this point, I've only attempted to write this as a generic method in the single enum type. I can't even get that working. I can't figure out how to extract the class from the template parameter. I've seen this particular question before, and there have been some answers, but I couldn't quite get it to work, and I imagine trying to do this in the base class would add additional complexity.

答案1

得分: 1

让我们假设我理解了您的问题(如果我理解错了,请纠正我)。

> 构造函数将更改为只调用 "super(messageValue)"

枚举无法扩展类,因此您不能这样做。但是您可以创建一个接口/类,用于处理此类查询(非常简化的代码):

interface Test {

    ObjectMapper MAPPER = new ObjectMapper();

    static <T extends Enum<T>> T getIt(String s, Class<T> clazz) {
        return MAPPER.convertValue(s, clazz);
    }

}

public static void main(String[] args)  {
    Thingie abc = Test.getIt("abc", Thingie.class);
    System.out.println(abc.ordinal());
}
英文:

Let's assume I understood your problem (correct me if I am wrong).

> The constructor would change to just call "super(messageValue)"

An enum can not extend a class, so you can't do that. But you can create an interface/class which you will delegate to for such queries (very simplistic code):

interface Test {

    ObjectMapper MAPPER = new ObjectMapper();

    static &lt;T extends Enum&lt;T&gt;&gt; T getIt(String s, Class&lt;T&gt; clazz) {
        return MAPPER.convertValue(s, clazz);
    }

}


public static void main(String[] args)  {
    Thingie abc = Test.getIt(&quot;abc&quot;, Thingie.class);
    System.out.println(abc.ordinal());
}

huangapple
  • 本文由 发表于 2020年10月8日 08:32:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/64254153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定