Java 通过反射从实例获取泛型类型
让我从一个可能重复的免责声明开始。。。我确实试着仔细研究了一些关于这个话题的问题,但它们并不代表我对我想要实现的目标的挑战。所以请宽容我,帮助我解决问题 以下是我的情况: 我有一个接口(在命令模式中),如下所示,我需要为其实现Java 通过反射从实例获取泛型类型,java,generics,Java,Generics,让我从一个可能重复的免责声明开始。。。我确实试着仔细研究了一些关于这个话题的问题,但它们并不代表我对我想要实现的目标的挑战。所以请宽容我,帮助我解决问题 以下是我的情况: 我有一个接口(在命令模式中),如下所示,我需要为其实现 public interface IIntelligentAction<E> { /** * Set dynamic variable for this action. */ public void setDynamicO
public interface IIntelligentAction<E> {
/**
* Set dynamic variable for this action.
*/
public void setDynamicOperand(Callable<?> getter);
/*
* Set validating operand for this action.
*/
public void setValidatingOperand(Callable<?> getter);
/*
* The implementation must check if the operands (dynamic and validating) are
* compatible with each other for this action.
*/
public boolean areOperandsCompatible();
/*
* Execute this action.
* <p> The implementation must check for both operands being assigned and are
* compatible with each other, before allowing the action to execute.
*/
public void execute();
}
公共接口智能操作{
/**
*为此操作设置动态变量。
*/
公共void setDynamicOperand(可调用getter);
/*
*设置此操作的验证操作数。
*/
public void setValidatingOperand(可调用的getter);
/*
*实现必须检查操作数(动态和验证)是否正确
*对于此操作,彼此兼容。
*/
公共布尔运算对象是可兼容的();
/*
*执行此操作。
*实现必须检查两个被赋值的操作数,并且
*相互兼容,然后才允许执行操作。
*/
公共无效执行();
}
界面的设计是有意的,我理解其基本原理(例如,Date
和Calendar
在语义上兼容,但不兼容类型)
现在我关心的是
操作数兼容()
方法。可以看出,该方法接受参数化的可调用的
,因此通过反射,我将始终看到可调用的
,但不会看到它将返回的类型。如何访问从setter方法获得的泛型实例的参数化类型?我最终实现此问题解决方案的方式他与下列人士保持联系:
public Class<?> getGenericsTypeDeclared(Object any) {
List<Type> classScope = new ArrayList<Type>();
classScope.add(any.getClass());
classScope.add(any.getClass().getGenericSuperclass());
for (Type type : any.getClass().getGenericInterfaces())
classScope.add(type);
Class<?> genericType = null;
for (Type type : classScope) {
try {
genericType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
} catch (ClassCastException e) {
if (logging != null)
logging.warn("Ignoring non-generic type: " + type);
} catch (ArrayIndexOutOfBoundsException e) {
if (logging != null)
logging.warn("Oddly Generic type without parameters. Found: " + type);
}
if (genericType != null) {
return genericType.getClass();
}
}
return null;
}
公共类getGenericsTypeDeclared(对象任意){
List classScope=new ArrayList();
添加(any.getClass());
添加(any.getClass().getGenericSuperclass());
for(类型:any.getClass().getGenericInterfaces())
添加(类型);
类genericType=null;
for(类型:classScope){
试一试{
genericType=(类)((ParameteredType)类型).getActualTypeArguments()[0];
}catch(ClassCastException e){
if(记录!=null)
logging.warn(“忽略非泛型类型:“+type”);
}捕获(阵列索引边界外异常e){
if(记录!=null)
logging.warn(“没有参数的奇怪泛型类型。找到:“+type”);
}
if(genericType!=null){
返回genericType.getClass();
}
}
返回null;
}
该方法使用本机java,因此不需要任何第三方库。希望它能帮助其他搜索类似需求的人。我认为这是不可能的,因为类型擦除。您可以将类与
Callable
一起传递给该方法,然后在需要时在运行时使用它。您的Callable
没有任何类型parameter,它们使用通配符类型。不清楚您要检查什么。也不清楚
在哪里起作用。您的意思是要执行可调用
?您可能可以使用前面提到的构造,但只有当您有一个提供具体类型参数的子类,如类MyCallable implem时,这才有效ents可调用{…}
。如果有类,MyCallable实现可调用{…}
那么反射就不起作用了。如果你不明白反射什么时候起作用/为什么起作用,那么传递一个类
比任何其他选项都要容易得多。你找到解决方案了吗?我有一个类似的要求来比较泛型类型的兼容性,例如日期
和日历
在语义上是一致的在Java中不兼容但类型不兼容。您的解决方案将对我有很大帮助。