[英]Associating a generic type with Enum in Java
我正在为用户首选项创建商店,并且用户可以为其设置固定数量的首选项。 首选项(设置)的名称存储为枚举:
public enum UserSettingName {
FOO,
BAR,
ETC
}
我希望能够做的是存储一个带有名称的值类型,以便服务将使用正确的Java类型存储用户的值。 例如,FOO可能是Long
,BAR可能是String
。 到目前为止,我们将所有值存储为String
,然后手动将值转换为适当的Java类型。 这导致了无处不在的try / catch块,当在服务中只有一次try / catch更有意义时。 我知道Enums不能有通用类型,所以我一直在玩:
public enum UserSettingName {
FOO(Long.class),
BAR(String.class),
ETC(Baz.class)
private Class type;
private UserSettingName(Class type) {
this.type = type;
}
public Class getType() {
return this.type;
}
}
我有一个通用的UserSetting对象,它具有public T getSettingValue()
和public void setSettingValue(T value)
方法,它们应返回并使用正确的类型设置值。 我的问题来自于在创建或检索设置时尝试指定泛型类型T
,因为我无法执行以下操作:
new UserSetting<UserSettingName.FOO.getType()>(UserSettingName.FOO, 123L)
对不起,如果不是很清楚,我可以尝试澄清它是否被理解。
谢谢!
UPDATE
设置名称和值都来自Spring MVC REST调用:
public ResponseEntity<String> save(@PathVariable Long userId, @PathVariable UserSettingName settingName, @RequestBody String settingValue)
所以我使用了Enum,因为Spring会自动转换传入的数据。
首先,你必须退后一步,思考你想要实现的目标,并使用标准模式或语言结构来实现它。
目前还不完全清楚你要追求的是什么,但从你的方法来看,几乎可以肯定你正在重新发明一些可以用更直接的方式在Java中完成的事情。 例如,如果您确实需要了解并使用对象的运行时类,请考虑使用反射API。
在更实际的层面上 - 你在这里尝试做的事情是泛型的。 泛型是一种编译时语言特性 - 它们有助于避免从Object显式地转换所有内容,并在编译时为您提供类型检查。 你不能以这种方式使用泛型,即将T
设置为某个值UserSettingName.Foo.getType()
,它只在运行时已知。
看看它如何通过netty完成:
http://netty.io/wiki/new-and-noteworthy.html#type-safe-channeloption
他们通过使用类型常量来完成它:
编辑:
public interface ChannelConfig {
...
<T> boolean setOption(ChannelOption<T> option, T value);
...
}
public class ChannelOption<T> ...
public static final ChannelOption<Integer> SO_TIMEOUT =
new ChannelOption<Integer>("SO_TIMEOUT");
...
}
EDIT2:你可以改变它:
class Baz {}
class UserSettingName<T> {
public static final UserSettingName<Baz> ETC = new UserSettingName<Baz>();
}
class UserSetting {
public <T> UserSetting(UserSettingName<T> name, T param) {
}
}
public class Test {
public static void main(String[] args) {
new UserSetting(UserSettingName.ETC, new Baz());
}
}
枚举不是这里的答案。 如果你发现自己在任何地方重复代码,你可以创建一个实用程序类并在那里封装所有的try / catch逻辑。 这将减少您的代码冗余,而不会对您当前的代码产生重大影响。
public class Util
{
public static MyObject getObjectFromString(String s)
{
try
{
return (MyObject)s;
}
catch(Exception e)
{
return null;
}
}
}
然后使用如下:
MyObject myObj = Util.getObjectFromString(string);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.