Community
Participate
Working Groups
public class Test { final static private int constant = 1; public static void main(String[] args) { T(); } public static void T(){} } public privileged aspect TestAspect { before(): call(public void Test.T()){ switch(1){ case Test.constant: System.out.println("hello"); default: } } } When compiling the above code, I will get "case expression must be constant expressions" error at the case statement of the switch block. The aspect class is already declared as privileged, so it should be able to access the static private field, constant, of the Test class Dapeng Gao
I suspect it's due to generated accessor methods. Passing over to AspectJ component as it's a language issue.
for investigation in aj5m3...
class A { // only happens when the below line is non-static, or private static final int c = 1; void a() { switch(1){ case c: // this is fine } } } aspect B { before(A anA):execution(* a()) && this(anA){ switch(1){ case anA.c: // "case expressions must be constant expressions" } } } // hypothesis: // problem is that 'get' methods are made so that aspect B // can get the value of things in A. // but this doesn't work here, // because the 'get' method doesn't count as a constant expression // (it could have side effects, etc) // // possible solution: // if the thing in class A is a constant expression // make a 'get' constant expression for it instead... // like "final int getC = c" // instead of "final int getC(){return c}
not going to get to this for M3
The discussion in the bug is correct. In order for the non-public field to be accessible to the advice in the aspect, we have to create an accessor method. (That's how privileged works). We do not hack the visibility of the field so that the aspect can see it. References to the non-public field from outside of the type are converted to references to the accessor method. This is invalid in a switch statement so you get the compile error. It is not a trivial piece of work to modify the accessor infrastructure to behave differently for final fields - and given the workaround is: privileged aspect TestAspect { before(): call(public void Test.T()){ if (1==Test.constant) { System.out.println("hello"); } } } I'm proposing we dont do this for 1.5.0 (this problem has existed since AspectJ1.2 and earlier, its not new). For 1.5 I could possibly put out a better error message for this situation.
new message added that is a little more intuitive. moving this bug out of 1.5.0 now...