当前位置: 首页 > 知识库问答 >
问题:

对具有基元数字返回类型的方法的反思

邹禄
2023-03-14

我目前正在开发一个小框架来收集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将是。该死的。冘。

然后我创建了一个地图

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),让边界检查

最后,这种组合奏效了:

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

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

我想知道除了维护int的Map之外,是否还有其他方法可以解决这个问题-

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

有人能对此有所了解吗?


共有1个答案

濮阳浩穰
2023-03-14

反射表示对象的返回类型(int.class)不可分配给Number。类,但当我继续调用方法时,我实际上得到了一个Integer.class?

绝对。反射 API 不可能返回实际的 int,因此它将值装在整数中。它还能做什么?

它必须框的事实不会将可分配性从int更改为数字。查看isAsSignablefrom的文档:

如果此类对象表示原始类型,则如果指定的类参数正是此类对象,则此方法返回true;否则返回false。

所以它完全按照留档行事。

我想知道除了维护int的Map之外,是否还有其他方法可以解决这个问题-

是的,听起来对我来说是对的。或者只是有一个

 类似资料:
  • 问题内容: 我目前正在使用一个小型框架来收集OSGi系统中的指标。它的核心是注释@Metric,它指示服务的给定方法可以在被询问时传递指标(例如,数值)。 这些方法看起来像: 要么 我正在使用反射来检查服务实现类并注册带有注释的方法。作为健全性检查,我正在检查该方法确实提供了一个数值。我尝试了这个但失败了: 然后,稍后在处理器上,我将执行以下操作: 事实证明,对于原始类型,您将得到例如,并且它不能

  • 问题内容: 我在接口上苦苦挣扎。考虑一下: 我希望函数返回a 或an ,具体取决于是否从或调用 当我尝试对此进行编译时,出现以下错误: 不能将s( StringGenerator类型)用作数组或切片文字中的Generator类型: StringGenerator不实现Generatorer(getValue方法的类型错误) 有getValue()字符串 要getValue() 我该如何实现? 问题

  • 问题内容: 假设我有一个超类,它定义了以下抽象方法 现在,如果我想在某些子类中覆盖它 我收到有关类型安全和未经检查的转换的警告: 类型安全:返回类型为从类型需要选中转换,以符合从类型 没有下摔倒,如果?有什么办法可以适当消除警告吗? 问题答案: 重写方法的返回类型必须是重写方法的返回类型的子类型。 不是where 的子类型。T在这里未知。 是每个子类型化规则的的子类型。 有关通配符的一些子类型化规

  • 问题内容: 对于一个抽象类,我想定义一个为子类返回“ this”的方法: 我希望能够执行以下操作: 可以说香蕉面包会抛出一个IllegalArgumentException消息“不是蛋糕!”。 问题答案: 编辑 要求子类以某种方式表现是没有问题的,这超出了静态类型可以检查的范围。我们一直在这样做-一页又一页的普通英语指定您如何编写子类。 提出的另一种具有协变返回类型的解决方案必须做同样的事情-用简

  • 有没有办法告诉Java不要试图从使用基元类型的方法引用中推断类型? 这是我写的一个方法,原因现在无关紧要: 现在,如果您将方法引用传递给返回原始类型的“isEquals”,该怎么办? 这一切都很好,但Java也会接受这种奇怪的用法: 这是因为编译器将推断类型参数T为"

  • (沙盒) 获取此错误: 类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。 我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢