对具有原始数字返回类型的方法的反思

我目前正在开发一个小型框架来收集OSGi系统中的指标。 它的核心是注释@Metric,它指示服务的给定方法在被询问时可以提供度量(例如数值)。

这些方法看起来像:

@Metric public int getQueueSize() {...} 

要么

 @Metric public double getAvgTaskTime() {...} 

我正在使用reflection来检查服务实现类并注册使用@Metric注释的方法。 作为一个完整性检查,我正在检查该方法确实提供了一个数值。 我试过这个并且失败了:

 for (Method method: metricSource.getClass().getMethods()) { if (method.isAnnotationPresent(Metric.class) && Number.class.isAssignableFrom(method.getReturnType()) { // add method for later process } 

然后,稍后在处理器上,我会做:

 Number value = (Number) method.invoke(target, obj[]); 

事实certificate,对于一个原始类型,你会得到例如int.class并且它不能分配给Number.class,而盒装类型Integer.class则是。 该死的。 继续。

然后我创建了一个Map<Class, Extractor> ,其中Extractor接受一个类并将一个参数强制转换为该类:

 public NumberExtractor(Class clazz) { this.clazz = clazz; } public double extract(Object val) { Number nbr = clazz.cast(val); return nbr.doubleValue(); } } 

面对之前的观察,我添加了一个这样的条目:

 extractorMap.put(int.class, new NumberExtractor(int.class)); 

但这也不起作用。 它给出了一个运行时类强制转换exception,说Integer.class无法强制转换为int。 还要注意编译器不会在new NumberExtractor(int.class)上抱怨,让边界检查Class Class int.class Class传递int.class

最后,这个组合工作:

 extractorMap.put(int.class, new NumberExtractor(Integer.class)); 

这里发生了什么? Reflection说对象的返回类型(int.class)不能赋值给Number.class,但是当我继续调用方法时,我实际上得到了一个Integer.class? WhiskeyTangoFoxtrot?

我想知道是否有另一种方法可以解决这个问题,除了维护int的地图 – >整数,整数 – >整数,浮点 – >浮点数,浮点数 – >浮点数? (现在已经完成了,所以这是为了学习)

拳击和类型信息的行为在这里似乎并不一致。

有人可以对此有所启发吗?

Reflection说对象的返回类型(int.class)不能赋值给Number.class,但是当我继续调用方法时,我实际上得到了一个Integer.class?

绝对。 reflectionAPI 不可能返回实际的int ,因此它将值装入Integer 。 它还能做什么?

它必须为box的事实不会改变从intNumber的可赋值性。 查看isAssignableFrom的文档 :

如果此Class对象表示基本类型,则如果指定的Class参数恰好是此Class对象,则此方法返回true;否则返回true。 否则返回false。

所以它的行为完全符合文档。

我想知道是否有另一种方法可以解决这个问题,除了维护int的地图 – >整数,整数 – >整数,浮点 – >浮点数,浮点数 – >浮点数? (现在已经完成了,所以这是为了学习)

是的,这对我来说是对的。 或者只是为原始数字类型Set一个Set而不是显式映射。