Summary: | Problems checking override/hiding rules for LTW of decp | ||
---|---|---|---|
Product: | [Tools] AspectJ | Reporter: | Andrew Clement <aclement> |
Component: | Compiler | Assignee: | Andrew Clement <aclement> |
Status: | RESOLVED FIXED | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | ||
Version: | DEVELOPMENT | ||
Target Milestone: | 1.5.2 | ||
Hardware: | PC | ||
OS: | Windows XP | ||
Whiteboard: |
Description
Andrew Clement
2006-04-19 07:45:08 EDT
I investigated what was actually going on and although they are both static, static methods have to obey some rules. From the Java Spec, 8.4.6.2: If a class declares a static method then the declaration of that method is said to hide any and all methods with the same signature in the superclasses. From 8.4.6.3: If a method declaration overrides or hides the declaration of another method, then a compile-time error occurs if they have different return values or if one has a return type and the other is void. So, this will fail to compile ====8<========= A.java ======== import java.util.*; class A { static List foo() { return null; } } class B extends A { static String foo() { return null; } } ====8<========= A.java ======== javac A.java A.java:8: foo() in B cannot override foo() in A; attempting to use incompatible return type found : java.lang.String required: java.util.List The problem in this failing scenario is that these are synthetic accessor methods and you kind of have 'no control' over what gets created, so let's compile this program: ====8<========= A.java ======== import java.util.*; class A { private static List o; static class Inner { List foo() { return o; } } } class B extends A { private static String o; static class Inner { String foo() { return o; } } } ====8<========= A.java ======== Both A and B need a synthetic accessor method created so that 'o' can be reached from the inner type. If we javap the output, we see: >javap A class A extends java.lang.Object{ A(); static java.util.List access$000(); } >javap B class B extends A{ B(); static java.lang.String access$000(); } You can see the access$000() breaks the rules above but that is OK in this case because the accessors are used locally inside the type - so my fix is to ignore return type compatibility when the methods are synthetic. fix committed, waiting on build. build available. |