-
Notifications
You must be signed in to change notification settings - Fork 82
MrBean: Fix detection of inherited default method in Java 8+ interface #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c18cdeb
286b5d9
c5176ab
92e61bb
e0bfe3f
e800726
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -181,16 +181,28 @@ protected boolean hasConcreteOverride(Method m0, JavaType implementedType) | |
{ | ||
final String name = m0.getName(); | ||
final Class<?>[] argTypes = m0.getParameterTypes(); | ||
try { | ||
// getMethod returns the most-specific method implementation, for public methods only (which is any method in an interface) | ||
Method effectiveMethod = implementedType.getRawClass().getMethod(name, argTypes); | ||
if (BeanUtil.isConcrete(effectiveMethod)) { | ||
return true; | ||
} | ||
} catch (NoSuchMethodException e) { | ||
// method must be non-public, fallback to using getDeclaredMethod | ||
} | ||
|
||
for (JavaType curr = implementedType; (curr != null) && !curr.isJavaLangObject(); | ||
curr = curr.getSuperClass()) { | ||
// 29-Nov-2015, tatu: Avoiding exceptions would be good, so would linear scan | ||
// be better here? | ||
try { | ||
Method effectiveMethod = curr.getRawClass().getDeclaredMethod(name, argTypes); | ||
if (effectiveMethod != null && BeanUtil.isConcrete(effectiveMethod)) { | ||
if (BeanUtil.isConcrete(effectiveMethod)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently any "re-abstracted" methods are skipped over by this check. If the concrete method exists on a class other than I'll write a test case to confirm this behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much appreciated! It's good that we can keep modules up to date with "new" versions of JDK (Java 8 isn't that new of course, but it wasn't around when Mr Bean was written and still isn't the baseline). |
||
return true; | ||
} | ||
} catch (NoSuchMethodException e) { } | ||
} catch (NoSuchMethodException e) { | ||
// method must exist on a superclass, continue searching... | ||
} | ||
} | ||
return false; | ||
} | ||
|
@@ -245,7 +257,7 @@ protected final static boolean returnsBoolean(Method m) | |
Class<?> rt = m.getReturnType(); | ||
return (rt == Boolean.class || rt == Boolean.TYPE); | ||
} | ||
|
||
/* | ||
/********************************************************** | ||
/* Internal methods, bytecode generation | ||
|
@@ -354,7 +366,7 @@ protected void createUnimplementedMethod(ClassWriter cw, String internalClassNam | |
/* Internal methods, other | ||
/********************************************************** | ||
*/ | ||
|
||
protected String decap(String name) { | ||
char c = name.charAt(0); | ||
if (name.length() > 1 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick question on this one: is the other case (not concrete) not conclusive?
That is, why not just return
BeanUtil.isConcrete(effectiveMethod)
as is, instead of continuing?I am assuming here that if method is found, it is the visible declaration.
I suspect most of the time continuing would only be wasteful and is unlikely to give wrong answer....
but I have occasionally used pattern of re-abstract'ing methods (esp.
toString()
/equals()
fromObject
) to force re-implementing by sub-classes.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's an interesting thought. Yes... if the method is returned, then I think you have the definitive answer as to whether the method is concrete for the implemented type.
I think if the implemented type returned one of those "re-abstracted" methods, then it would be abstract, and the MrBean-generated class would be required to provide an implementation. I'm not sure how MrBean would handle this, probably it would throw an error, since it's not a property?
So, to clarify what we're talking about, I think it would be correct to simply
return BeanUtil.isConcrete(effectiveMethod)
here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok cool.