当前位置: 首页 > 面试题库 >

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

陆文斌
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。该死的。继续。

然后,我创建了一个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吗?威士忌TangoFoxtrot?

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

此处的装箱和类型信息的行为似乎不一致。

有人能对此有所启发吗?


问题答案:

反射说对象的返回类型(int.class)不能分配给Number.class,但是当我继续进行方法调用时,实际上得到的是Integer.class吗?

绝对。反射API不能 可能 返回你实际的int,所以它在盒子的价值Integer。它还能做什么?

它必须装箱的事实 不会
将可分配性从更改intNumber。查看以下文档isAssignableFrom

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

因此,它的行为完全符合文档规定。

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

是的,对我来说听起来不错。或者只Set<Class>为原始数字类型提供一个,而不是显式映射。



 类似资料:
  • 我目前正在开发一个小框架来收集OSGi系统中的指标。它的核心是一个注释@Metric,它指示服务的给定方法可以在被询问时提供一个指标(例如数值)。 这些方法看起来像: 或 我使用反射来检查服务实现类,并注册用注释的方法。作为健全性检查,我正在检查该方法是否确实传递了一个数值。我尝试过,但失败了: 然后,稍后在处理器上,我会这样做: 事实证明,对于原始类型,你会得到例如int.class并且不能分配

  • JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟原始类型不是对象(在这里我们会分析地更加清楚)。 我们来看看原始类型和对象之间的关键区别。 一个原始值: 是原始类型中的一种值。 在 JavaScript 中有 7 种原始类型:string,number,bigint,

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

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

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

  • 问题内容: 我的测试框架中有一个方法可以创建类的实例,具体取决于传入的参数: 问题是,如果构造函数具有基本类型,则这将不起作用,如下所示: 结果是: 原始int会自动装箱到对象版本中,但是如何返回它们以调用构造函数? 问题答案: 使用代替。 根据Javadocs,这是“表示原始类型的Class实例”。 您也可以使用。这是的快捷方式。不仅是类,甚至对于原始类型,您都可以用Java表示。