[英]What determines the return order of Class.getMethods()?
This question is not looking for a solution to a problem but an explanation of why a problem may have arisen (or not!). 这个问题不是寻找问题的解决方案,而是解释为什么可能出现问题(或不是!)。
The Javadocs for Class.getMethods()
say: Class.getMethods()
的Javadocs说:
The elements in the array returned are not sorted and are not in any particular order. 返回的数组中的元素没有排序,也没有任何特定的顺序。
The thing is, this: we've been using a neat little Java templating library called JMTE for maybe a couple of years now, with no problems. 问题是:我们一直在使用一个名为JMTE的整洁的小Java模板库,可能已经有几年了,没有任何问题。 This uses JSTL-like syntax to inject model values into templates. 这使用类似JSTL的语法将模型值注入模板。 In particular, we've been using something like this to render a price: 特别是,我们一直在使用这样的东西来代价:
${vendor.currency.symbol} ${order.amount}
The first of these translates to the the following: 第一个转换为以下内容:
vendor.getCurrency().getSymbol()
where getCurrency()
returns a java.util.Currency object. 其中getCurrency()
返回java.util.Currency对象。 Currency has two methods for getting the currency symbol - one that takes a specific Locale and one that uses the default. 货币有两种获取货币符号的方法 - 一种采用特定的Locale,另一种采用默认的。
public String getSymbol(Locale locale)
For the last 18 months or so, everything has been running fine, with currency codes/symbols appearing in emails. 在过去的18个月左右,一切运行正常,电子邮件中出现货币代码/符号。 Then 5 days ago, we started getting a random IllegalArgumentException
thrown when trying to substitute ${vendor.currency.symbol}
然后5天前,当我们尝试替换${vendor.currency.symbol}
时,我们开始抛出一个随机的IllegalArgumentException
After a bit of debugging I found the cause, deep inside JMTE: 经过一些调试后,我发现了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);
....
}
}
ie, Whether getSymbol()
or getSymbol(Locale)
was called is completely at the mercy of the return order of Class.getMethods()
( not in any particular order ). 即,是否getSymbol()
或getSymbol(Locale)
完全getSymbol(Locale)
Class.getMethods()
的返回顺序( 不是以任何特定的顺序 )。 I added a test to ensure the method has 0 parameters and my problem was solved. 我添加了一个测试,以确保方法有0参数,我的问题解决了。
Now, by a strange coincidence, someone else happened to submit an identical fix on the very same day that we first observed this behaviour. 现在,由于一个奇怪的巧合,其他人碰巧在我们第一次观察到这种行为的同一天提交了相同的修复 。
What's puzzling is that this code has been running for 18 months with no problems, then all of a sudden, this behaviour appears. 令人费解的是,这段代码已经运行了18个月而没有任何问题,然后突然出现这种行为。
When I created a test case it failed roughly 50% of the time, as one would expect (there are 2 matching methods, returned in no particular order), so I'm puzzled (amazed) it worked for 18 months and 10^5 executions. 当我创建一个测试用例时,它大约有50%的时间失败,正如人们所期望的那样(有两种匹配的方法,没有特定的顺序返回),所以我很困惑(惊讶)它工作了18个月和10 ^ 5处决。 (It's conceivable, but unlikely, that it has failed but succeeded on subsequent retries). (可以想象,但不太可能,它已经失败但在随后的重试中取得了成功)。
Purely out of curiosity , I'm wondering if there's anything in the Java runtime that might cause this latent behaviour to suddenly appear. 纯粹出于好奇 ,我想知道Java运行时中是否有任何可能导致这种潜在行为突然出现的东西。 It's even more puzzling that a fix for this behaviour should be provided by someone else on the same day for a project that is mature and stable - suggesting perhaps that the same latent behaviour suddenly realised itself elsewhere. 更令人费解的是,在同一天,其他人应该为一个成熟稳定的项目提供这种行为的解决方案 - 这可能意味着同样的潜在行为突然在其他地方实现了。
So, the question is: does anyone know what factors might influence the order of the methods returned by Class.getMethods()
? 所以,问题是:有没有人知道哪些因素可能会影响Class.getMethods()
返回的方法的顺序?
The relevant Java code that can be seen from getMethods()
shows a lot of checking for cached data, but the final say is up to this implementation: 从getMethods()
可以看到的相关Java代码显示了很多对缓存数据的检查,但最后的说法取决于这个实现:
private native Method[] getDeclaredMethods0(boolean publicOnly);
Therefore it's VM dependent, and a very poor idea to trust the order simply because "it was the same one a lot of times". 因此,它依赖于VM,并且仅仅因为“它很多次都是相同的”而非常缺乏信任该命令的想法。
The caching affects it certainly, since if it's fetched correctly the first time, it'll work for the subsequent times as well unless the cache is cleared (there's some soft reference business and such going on). 缓存肯定会影响它,因为如果它第一次正确获取,它将在随后的时间工作,除非缓存被清除(有一些软参考业务等等)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.