泛型类型的Java枚举
我想为IBatis创建一个基于枚举的通用映射器。我用下面的代码来做这件事。这确实有编译时错误,我不知道如何修复。也许我的解决方案是完全错误的(请记住使用IBatis),在这种情况下,请提出更好的建议 谢谢你的帮助 我想要实现的是将后续映射器定义为:泛型类型的Java枚举,java,generics,enums,Java,Generics,Enums,我想为IBatis创建一个基于枚举的通用映射器。我用下面的代码来做这件事。这确实有编译时错误,我不知道如何修复。也许我的解决方案是完全错误的(请记住使用IBatis),在这种情况下,请提出更好的建议 谢谢你的帮助 我想要实现的是将后续映射器定义为: public class XEnumTypeHandler extends CommonEnumTypeHandler<X> { } 公共类XEnumTypeHandler扩展了CommonEnumTypeHandler{ } 当前代
public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
}
公共类XEnumTypeHandler扩展了CommonEnumTypeHandler{
}
当前代码:
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;
}
}
公共类CommonEnumTypeHandler实现TypeHandlerCallback{
公共void setParameter(参数设置器ps,对象o)引发SQLException{
如果(o.getClass().isAssignableFrom(**T**)){
ps.setString(((**T**)o.value().toUpperCase());
}否则
抛出新的SQLException(“异常参数类型对象:”+o);
}
公共对象getResult(ResultGetter rs)引发SQLException{
对象o=valueOf(rs.getString());
如果(o==null)
抛出新的SQLException(“未知参数类型:+rs.getString());
返回o;
}
公共对象值(字符串s){
对于(T pt:T.*values()**){
如果(pt.*value()**.equalsIgnoreCase)
返回pt;
}
返回null;
}
}
我已将错误标记添加到上述代码中,错误消息的顺序如下:
- 这个问题无法解决
- 未为定义方法值() T型
- 对于,未定义方法值() T型
- 对于,未定义方法值() 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);
}
}
公共类CommonEnumTypeHandler实现TypeHandlerCallback{
课堂讨论;
公共CommonEnumTypeHandler(类clazz){
this.clazz=clazz;
}
公共void setParameter(参数设置器ps,对象o)引发SQLException{
if(o.getClass().isAssignableFrom(clazz)){
ps.setString(((T)o.name().toUpperCase());
}否则
抛出新的SQLException(“异常的”+clazz+”对象,而不是“+o”);
}
公共对象getResult(ResultGetter rs)引发SQLException{
对象o=valueOf(rs.getString());
如果(o==null)
抛出新的SQLException(“未知参数类型:+rs.getString());
返回o;
}
公共对象值(字符串s){
返回枚举值(clazz,s);
}
}
从这个类继承我做:
public class SalesChannelTypeHandler extends CommonEnumTypeHandler<SalesChannel> {
public SalesChannelTypeHandler() {
super(SalesChannel.class);
}
public SalesChannelTypeHandler(Class<SalesChannel> clazz) {
super(clazz);
}
}
公共类SalesChannelTypeHandler扩展了CommonEnumTypeHandler{
公共SalesChannelTypeHandler(){
超级(SalesChannel.class);
}
公共SalesChannelTypeHandler(clazz类){
超级(clazz);
}
}
我不确定你在做什么(用文字概括一下就好了),但是:
- 您不能从(t)执行
(您需要一个isAssignableFrom(t)
对象),也不能执行类
(泛型是非具体化的)。您可能希望传递t的instanceof
类型令牌类
- 你看过吗
我们仍然不清楚想要什么,但也许是这样的:
enum Color { BLACK, WHITE; }
public static void main(String[] args) {
Color c = Enum.valueOf(Color.class, "black".toUpperCase());
System.out.println(c); // prints "BLACK"
}
因此,我们使用它获取一个类型标记
Class
,并要求它使用给定名称获取enum
常量valueOf
不区分大小写,但按照惯例,所有常量都应该是大写的,因此我们只需获取查询字符串并将其转换为.toUpperCase()
,正如PolyGene所指出的,您需要传递具体的运行时类型,例如,Class
,而不是像泛型参数这样的语法编译时类型。以下是您如何使用它的重写:
public abstract class CommonEnumTypeHandler<E extends Enum<E>> implements TypeHandlerCallback {
private Class<E> enumClass;
public CommonEnumTypeHandler(Class<E> enumClass) {
this.enumClass = enumClass;
}
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (enumClass.isInstance(o)) {
ps.setString((enumClass.cast(o)).name().toUpperCase());
} else {
throw new SQLException("Excpected ParameterType object than: " + o);
}
}
public Object getResult(ResultGetter rs) throws SQLException {
try {
return Enum.valueOf(enumClass, rs.getString());
} catch (IllegalArgumentException e) {
throw new SQLException("Unknown parameter type: " + rs.getString(), e);
}
}
}
公共抽象类CommonEnumTypeHandler实现TypeHandlerCallback{
私有类;
公共CommonEnumTypeHandler(类enumClass){
this.enumClass=enumClass;
}
公共void setParameter(参数设置器ps,对象o)引发SQLException{
if(枚举类isInstance(o)){
ps.setString((enumClass.cast(o)).name().toUpperCase());
}否则{
抛出新的SQLException(“异常参数类型对象:”+o);
}
}
公共对象getResult(ResultGetter rs)引发SQLException{
试一试{
返回Enum.valueOf(enumClass,rs.getString());
}捕获(IllegalArgumentException e){
抛出新的SQLException(“未知参数类型:”+rs.getString(),e);
}
}
}
然后,您可以按如下方式使用:
public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
public XEnumTypeHandler() {
super(X.class);
}
}
公共类XEnumTypeHandler扩展了CommonEnumTypeHandler{
公共XEnumTypeHandler(){
超级(X级);
}
}
请添加编译器错误和您实际尝试执行的操作的说明achieve@Marcin:同样,您不能执行t.values()
,但是如果您传递Class
的类型标记,您将能够执行。我将给出一个例子,但我仍然不确定您在做什么。只是尝试编写一个通用的“从字符串到已定义类型的枚举”转换器。您传入一个字符串,说“test”并获取enum TestEnum。test@Marcin当前位置我理解你想要实现的目标,但要面对它:!您需要将其作为运行时方法参数传递,而不是作为compiletime泛型类型传递。也许构造函数很有用?@Marcin:那么你想要一个不区分大小写的Enum.valueOf@巴卢斯:好的,我现在明白了,但我不确定你们传递类令牌是什么意思。你能给我举一些这个用法的例子吗?我仍然不确定OP想要什么,但我还是会支持这个。我相信你是正确的=)在setParameter
中,将isAssignableFrom
更改为enumClass。isInstance(o)
@BalusC:无论你知道什么技能,我都想学。@poly:然后尝试重构所有内容,同时保持跨DB兼容。换言之:重新发明/;)@多基因润滑剂。与客户的长时间可用性会议。我得出了类似的解决方案,但巴勒斯比我领先了几秒钟。