java getmethods_java – 什么决定了Class.getMethods()的返回顺序?

这个问题不是寻找问题的解决方案,而是解释为什么可能出现问题(或不是!).

Class.getMethods()的Javadocs说:

The elements in the array returned are not sorted and are not in any particular order.

问题是:我们已经使用了一个简洁的小型Java模板库,名为JMTE,可能已经有几年了,没有任何问题.这使用类似JSTL的语法将模型值注入模板.特别是,我们一直在使用这样的东西来代价:

${vendor.currency.symbol} ${order.amount}

第一个转换为以下内容:

vendor.getCurrency().getSymbol()

其中getCurrency()返回java.util.Currency对象.货币有两种获取货币符号的方法 – 一种采用特定的Locale,另一种采用默认的.

在过去的18个月左右,一切运行正常,电子邮件中出现货币代码/符号.然后5天前,当我们尝试替换${vendor.currency.symbol}时,我们开始抛出一个随机的IllegalArgumentException

经过一些调试后,我发现了JMTE内部的原因:

for (Method method : declaredMethods) {

if (Modifier.isPublic(method.getModifiers())

&& (method.getName().equals("get" + suffix) ||

method.getName().equals("is" + suffix))) {

value = method.invoke(o, (Object[]) null);

....

}

}

即,是否调用了getSymbol()或getSymbol(Locale)完全取决于Class.getMethods()的返回顺序(不是以任何特定的顺序).我添加了一个测试,以确保方法有0参数,我的问题解决了.

现在,由于一个奇怪的巧合,其他人碰巧在我们第一次观察到这种行为的同一天提交了identical fix.

令人费解的是,这段代码已经运行了18个月而没有任何问题,然后突然出现这种行为.

当我创建一个测试用例时,它大约有50%的时间失败,正如人们所期望的那样(有两种匹配的方法,没有特定的顺序返回),所以我很困惑(惊讶)它工作了18个月和10 ^ 5处决. (可以想象,但不太可能,它已经失败但在随后的重试中取得了成功).

纯粹出于好奇,我想知道Java运行时中是否有任何可能导致这种潜在行为突然出现的东西.更令人费解的是,在同一天,其他人应该为一个成熟稳定的项目提供这种行为的解决方案 – 这可能意味着同样的潜在行为突然在其他地方实现了.

所以,问题是:有没有人知道哪些因素可能会影响Class.getMethods()返回的方法的顺序?

最佳答案 从getMethods()可以看到的相关Java代码显示了很多对缓存数据的检查,但最后的说法取决于这个实现:

private native Method [] getDeclaredMethods0(boolean publicOnly);

因此,它依赖于VM,并且仅仅因为“它很多次都是相同的”而非常缺乏信任该命令的想法.

缓存肯定会影响它,因为如果它第一次正确获取,它将在随后的时间工作,除非缓存被清除(有一些软参考业务等等).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值