泛型类型中的 Java 枚举
我想为 IBatis 创建一个通用的基于枚举的映射器。我正在使用下面的代码执行此操作。这确实存在编译时错误,我不知道如何修复。也许我的解决方案完全错误(请记住 IBatis 的使用),在这种情况下,请提出更好的建议。
任何帮助表示赞赏。
我想要实现的是将后续映射器定义为:
public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
}
当前代码:
public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (o.getClass().isAssignableFrom(**T**)) {
ps.setString(((**T**) o).value().toUpperCase());
} else
throw new SQLException("Excpected ParameterType object than: " + o);
}
public Object getResult(ResultGetter rs) throws SQLException {
Object o = valueOf(rs.getString());
if (o == null)
throw new SQLException("Unknown parameter type: " + rs.getString());
return o;
}
public Object valueOf(String s) {
for (T pt : T.**values()**) {
if (pt.**value()**.equalsIgnoreCase(s))
return pt;
}
return null;
}
}
我已在上面的代码中添加了错误标记,错误消息按顺序排列:
- T 无法解析
- The method value() is undefined for 类型 T
- 方法 value() 未定义 类型 T
- 方法 value() 未定义 类型 T
我已经用以下代码解决了这个问题:
public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {
Class<T> clazz;
public CommonEnumTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (o.getClass().isAssignableFrom(clazz)) {
ps.setString(((T) o).name().toUpperCase());
} else
throw new SQLException("Excpected " + clazz + " object than: " + o);
}
public Object getResult(ResultGetter rs) throws SQLException {
Object o = valueOf(rs.getString());
if (o == null)
throw new SQLException("Unknown parameter type: " + rs.getString());
return o;
}
public Object valueOf(String s) {
return Enum.valueOf(clazz, s);
}
}
从这个类继承,我这样做:
public class SalesChannelTypeHandler extends CommonEnumTypeHandler<SalesChannel> {
public SalesChannelTypeHandler() {
super(SalesChannel.class);
}
public SalesChannelTypeHandler(Class<SalesChannel> clazz) {
super(clazz);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定你在做什么(用文字进行一般概述会很好),但是:
isAssignableFrom(T)
(你需要一个Class
object),并且你也不能做instanceof T
(泛型是非具体化的)。您可能想要传递Class
类型令牌。EnumMap
< /a>?另请参阅
目前还不清楚需要什么,但也许是这样的:
所以我们使用
Enum.valueOf
接受类型标记Class> ;
,并向其询问具有给定名称的enum
常量。valueOf
NOT 不区分大小写,但按照惯例,所有 常量都应为大写,因此我们只需获取查询字符串并将其转换为 <代码>.toUpperCase()。I'm not sure what you're doing (a general overview in words would be nice), but:
isAssignableFrom(T)
(you need aClass
object), and you can't doinstanceof T
either (generics are non-reified). You may want to passClass<T>
type tokens instead.EnumMap
?See also
It's still not clear what is desired, but perhaps it's something along the lines of this:
So we use
Enum.valueOf
that takes a type tokenClass<T extends Enum<T>>
, and ask it for theenum
constant with a given name.valueOf
is NOT case-insensitive, but by conventions, all constants should be in uppercase, so we simply take the query string and turn it.toUpperCase()
.正如 Polygenelubricants 所指出的,您需要传递具体的运行时类型,例如
Class
而不是像泛型参数这样的语法编译时类型。以下是如何使用它的重写:然后您可以按如下方式使用它:
As pointed by Polygenelubricants, you need to pass concrete runtime types around, e.g.
Class<?>
instead of syntactic compiletime types like generic parameters. Here's a rewrite how you could use it:Which you can then use as follows: