gpt4 book ai didi

java - 对具有原始数字返回类型的方法的反射(reflection)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:17:44 28 4
gpt4 key购买 nike

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

这些方法看起来像:

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

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

我正在使用反射检查服务实现类并注册用 @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[]);

事实证明,对于原始类型,您会得到例如int.class这不能分配给 Number.class 而盒装类型 Integer.class 可以。该死。继续前进。

然后我创建了一个 Map<Class<?>, Extractor>其中 Extractor 采用一个类并将参数转换为该类:

public NumberExtractor(Class<? extends Number> 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));

但这也没有用。它给出了一个运行时类转换异常,指出 Integer.class 无法转换为 int。另请注意,编译器不会提示 new NumberExtractor(int.class) , 让边界检查 Class<? extends Number>传递int.class

最后,这个组合奏效了:

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

这是怎么回事?反射说对象的返回类型(int.class)不可分配给Number.class,但是当我继续调用方法时,我实际上得到了一个Integer.class?威士忌探戈狐步舞?!

我想知道除了维护 int -> Integer、Integer -> Integer、float -> Float、Float -> Float 的 Map 之外是否还有其他方法可以解决此问题? (现在已经完成了,所以这是为了学习)

装箱和类型信息的行为在这里似乎不连贯。

有人能对此有所启发吗?

最佳答案

Reflection says that the return type of the object (int.class) is not assignable to Number.class, but when I go on with the method invoke, I actually get a Integer.class?

当然。反射 API 不可能返回给你一个实际的 int , 所以它将值装在 Integer 中.它还能做什么?

它必须装箱的事实不会改变 int 的可分配性至 Number .看docs for isAssignableFrom :

If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.

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

I'm left wondering whether there is another way to address this issue other than maintaining the Map of int -> Integer, Integer -> Integer, float -> Float, Float -> Float? (which is now done, so this is for the sake of learning)

是的,这听起来对我来说是正确的。或者只是有一个 Set<Class>对于原始数字类型而不是显式映射。

关于java - 对具有原始数字返回类型的方法的反射(reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11764588/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com