initialization of final fields
Godmar Back
gback@cs.utah.edu
Wed Nov 3 14:57:00 GMT 1999
Hi,
[ I'm cc'ing Vincent Gay-Para, the author of the GNU javac replacement KJC
http://www.dms.at/kopi/kjc.html ]
I believe gcj may a bit too anal with regard to assignments to final
fields. As a result, it fails to compile class files produced by KJC
that pass verification under Sun's JDK.
Consider this program:
public class FinalInt {
final long t = System.currentTimeMillis();
public static void main(String []av) {
System.out.println(new FinalInt().t);
}
}
KJC compiles this program into the following bytecode as shown
by jcf-dump -c:
Method name:"<init>" public Signature: 17=()void
Attribute "Code", length:33, max_stack:1, max_locals:1, code_length:9
0: aload_0
1: invokespecial #29=<Method java.lang.Object.<init> ()void>
4: aload_0
5: invokespecial #32=<Method FinalInt.Block$ ()void>
8: return
Method name:"Block$" private Signature: 17=()void
Attribute "Code", length:32, max_stack:3, max_locals:1, code_length:8
0: aload_0
1: invokestatic #36=<Method java.lang.System.currentTimeMillis ()long>
4: putfield #21=<Field FinalInt.t long>
7: return
KJC moves the initialization of final variables into a hidden private
method called "Block$". This appears a sensible thing to do: by doing
it, the compiler doesn't have to repeat the same initializations if
the class has multiple constructors.
The resulting class file FinalInt.class executes just fine with
JDK 1.1.7 and JDK 1.2 under Linux, even when run with the -verify
option. (That should verify it, shouldn't it?)
>From grepping the VM Spec I also couldn't find a requirement that
the initialization of a final variable has to happen in the
constructor itself, and not in a private method invoked from a
constructor.
My suggestion: until GCJ can prove that an assignment to a final
variable is indeed illegal, could you make the error in
expr.c:expand_java_field_op suppressable?
Thanks,
- Godmar
More information about the Java
mailing list