Hi devs,
I’m working on trying to move our build to java 8 and I’ve noticed one important breaking
change in java 8 about how java chooses which overloaded method it uses.
The details are available here:
http://stackoverflow.com/a/30526908/153102
An example on XWiki that I’ve just fixed (with Thomas):
We had:
public static boolean matches(Filter filter, Extension extension)
{
return matches(filter, extension.get(filter.getField()));
}
public static boolean matches(Filter filter, Object element)
{
…
}
And <T> T get(String fieldName);
This worked in java 7 because T gets resolved to Object in java 7.
However in Java 8 they’ve improved the type inference and thus java 8 tries to find the
most specific method matching T, and there are 2:
- matches(Filter filter, Extension extension)
- matches(Filter filter, Object element)
According to java 8 rules the most specific one is matches(Filter filter, Extension
extension) since Extension extends Object.
Thus at runtime java 8 trie to call matches(Filter filter, Extension extension). However
extension.get(…) returns String. Hence it fails with a class cast error.
So this means that when we upgrade to java8 we could have cases when the wrong signature
is going to be called at runtime, leading to bugs…
We’ll need to be careful about that.
Thanks
-Vincent