[英]Java Enum - Store Type For Later Cast
我有一个枚举表示特定表中的所有列值。 现在我想存储一个每个枚举元素的类型,这个元素被查询以供稍后的转换。
public enum Value {
MEMBER1(?...?),
MEMBER2(?...?);
private final ?...? type;
Value(?...? type) {
this.type = type;
}
public ?...? getType() {
return type;
}
}
我现在不需要代替?...?
。 也许它的MyClassA.class
和Class
但是如何在这个操作中使用这个值:
MEMBER1.getType() instance = (MEMBER1.getType()) object;
对我来说,这对于与java进行数据库通信非常重要。
更新:我的意思是这个操作。
END UPDATE:存在逻辑错误。 如果我知道不同的类型,我可以简单地创建多个方法,因为我有一个api规范。
你是对的。 枚举应定义如下
public enum Value {
MEMBER1(String.class),
MEMBER2(Integer.class);
private final Class<?> type;
private Value(Class<?> type) {
this.type = type;
}
public Class<?> getType(){
return this.type;
}
}
第二部分实际上是你不想做的事情,因为你已经知道你想要将对象强制转换为什么类型(在你的情况下是MyClassA)所以你可以直接投射如下
//I know what is the target type so I don't have to fetch the type from my enum
MyClassA instance = (MyClassA) object;
一旦你需要在未知数据类型上构建你的逻辑,你可以做类似的事情
Object o = getTheObjectSomewhere();
if(o.getClass().isAssignableFrom(MEMBER1.getType()){
String s = (String) o;
System.out.println("Target type is string!");
doSomething();
} else if (o.getClass().isAssignableFrom(MEMBER2.getType()){
Integer i = (Integer) i;
System.out.println("Target type is integer!");
doSomethingElese();
}
也许您希望稍后根据对象的类型搜索列。 然后,您可以创建一个方法来获取列
public Value getColumnByObjectType(Object o){
for(Value v : Value.values()){
if(v.getType().equals(o.getClass()){
return v;
}
}
return null;
}
并使用它来搜索列
Object o = getObjectSomewhere();
Value column = getColumnByObjectType(o);
要根据下面的注释获取用户对象,您可以执行类似以下使用JPA的操作
public Object getUserObject(int id, Value v){
TypedQuery<?> q = DBUtils.getEntityManager().createQuery("select u.:column from User u where u.id = :id",v.getType());
q.setParameter("column", v.toString());
q.setParameter("id", id);
q.setMaxResult(1);
return q.getSingleResult();
}
您可以通过存储对象的Class并在必要时使用它来进行转换:
class Test {
public static void main(String[] arguments) throws Exception {
Object object = new MyClassA();
Class<MyClassA> clazz = Value.MEMBER1.getType();
MyClassA instance = clazz.cast(object);
System.out.println(instance);
}
}
enum Value {
MEMBER1(MyClassA.class),
MEMBER2(MyClassB.class);
private final Class<?> clazz;
Value(Class<?> clazz) {
this.clazz = clazz;
}
@SuppressWarnings("unchecked")
public <T> Class<T> getType() {
return (Class<T>) clazz;
}
}
class MyClassA { }
class MyClassB { }
如何将此值用于此操作:
MyClassA instance = (MEMBER1.getType()) object;
使用instanceof检查对象类型。
MyClassA instance;
if (object instanceof MyClassA && object instanceof MEMBER1.getType()){
instance = (MyClassA) object;
}
我有一个枚举表示特定表中的所有列值。 现在我想存储一个每个枚举元素的类型,这个元素被查询以供稍后的转换。
一般来说,这不可能按照您希望的方式完成。
你想要的是枚举用于保存异构类型安全容器的键(Essential Java,2nd Ed。)。
不幸的是,Java类对象是通用的(例如, String.class
是Class<String>
), Java枚举和泛型不能很好地结合在一起 。
虽然可以将Class对象存储为枚举中的字段,但您的Class对象将在该过程中丢失其类型信息。 当您访问该字段时,您仍需要手动重新确认类型链接...这将需要一个不安全的强制转换。 我不知道它有什么办法。
例如,您的枚举可能有一个名为colClassToken
的字段,您打算在其中存储表中关联列的类型:
public enum TableColumn {
MEMBER1(String.class),
MEMBER2(Integer.class);
private Class<?> e_colToken;
TableColumn(Class<?> tok) { this.e_colToken = tok; }
public Class<?> getColumnToken() { return this.e_colToken; }
:
:
}
您现在想要做的是使用Class对象的cast()
方法在您访问表中的列时重新声明类型链接(例如,使用类似的惯用法):
String myColumn = MEMBER1.getColumnToken().cast(myTable.getCol(MEMBER1));
但是,这不会编译。 因为类对象的类型已在枚举字段中丢失(并且因为您无法生成枚举),所以编译器无法保证cast()
操作的类型安全性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.