简体   繁体   English

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

[英]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()

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.

相关问题 在 Java 中使用 Class.getMethods() 是一项繁重的操作吗? - Is using Class.getMethods() a heavy operation in Java? Java Class.getMethods() 对覆盖方法的行为 - Java Class.getMethods() behavior on overridden methods 什么决定了 Comparator / Comparable 集合类中的升序或降序? - What determines ascending or descending order in Comparator / Comparable collection class? 奇怪的行为-Class#getDeclaredMethods vs getMethods - Weird behavior - Class#getDeclaredMethods vs getMethods 是什么决定了Lists包含非字母数字字符的Collections.sort中的排序顺序? - What determines sort order in Collections.sort where List contains non-alphanumeric characters? Scala Reflection:为什么getMethods可以返回val成员? - Scala Reflection : why getMethods can return the val members? “类变量的类型决定了该变量可以使用哪些方法名称”。 这意味着什么? - “The type of a class variable determines which method names can be used with the variable”. What does that mean? Spring MVC的哪个类或组件确定传递给Controller的RequestMapping方法参数的对象? - What class or component of Spring MVC determines the object passed into a Controller's RequestMapping method parameter? 是什么决定了Java中组件的可见性? - What determines component visibility in Java? 什么决定了此代码中的呼叫数量 - What determines the amount of calls in this code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM