Forward referencing is allowed during declarations when the undeclared variable is used in the LHS of an expression, but not if its in the RHS. Therefore, the following won't work :
class A
{
int a=h;
int h;
}
But the following code works :
class A
{
int a=this.h;
int h;
}
This will assign 0 to a as 0 is the default value of ints. Why did this work ? this refers to the present object, and it is being currently constructed. Why does the use of this make any difference ?
Come on guys! This is a really good question! I certainly want to know the answer.
That is really interesting. Here's the output from javap for two compiles. The first with the forward reference and the second without. Can't see any difference in what javap outputs.
class ForwardRefTest {
// int a = this.h; // for first compile
int h;
int a = h; // for second compile
}
/*
D:\JavaDevelopment\Testing\ForumQuestions3>javap -c -verbose ForwardRefTest
Compiled from "ForwardRefTest.java"
class ForwardRefTest extends java.lang.Object
SourceFile: "ForwardRefTest.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #5.#18; // java/lang/Object."<init>":()V
const #2 = Field #4.#19; // ForwardRefTest.h:I
const #3 = Field #4.#20; // ForwardRefTest.a:I
const #4 = class #21; // ForwardRefTest
const #5 = class #22; // java/lang/Object
const #6 = Asciz a;
const #7 = Asciz I;
const #8 = Asciz h;
const #9 = Asciz <init>;
const #10 = Asciz ()V;
const #11 = Asciz Code;
const #12 = Asciz LineNumberTable;
const #13 = Asciz LocalVariableTable;
const #14 = Asciz this;
const #15 = Asciz LForwardRefTest;;
const #16 = Asciz SourceFile;
const #17 = Asciz ForwardRefTest.java;
const #18 = NameAndType #9:#10;// "<init>":()V
const #19 = NameAndType #8:#7;// h:I
const #20 = NameAndType #6:#7;// a:I
const #21 = Asciz ForwardRefTest;
const #22 = Asciz java/lang/Object;
{
int a;
int h;
ForwardRefTest();
Code:
Stack=2, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: aload_0
6: getfield #2; //Field h:I
9: putfield #3; //Field a:I
12: return
LineNumberTable:
line 1: 0
line 2: 4
LocalVariableTable:
Start Length Slot Name Signature
0 13 0 this LForwardRefTest;
}
D:\JavaDevelopment\Testing\ForumQuestions3>javap -c -verbose ForwardRefTest
Compiled from "ForwardRefTest.java"
class ForwardRefTest extends java.lang.Object
SourceFile: "ForwardRefTest.java"
SourceDir: length = 0x2
00 1A
minor version: 3
major version: 45
Constant pool:
const #1 = Asciz Code;
const #2 = Asciz SourceFile;
const #3 = Asciz SourceDir;
const #4 = Asciz ConstantValue;
const #5 = Asciz Exceptions;
const #6 = Asciz LineNumberTable;
const #7 = Asciz LocalVariableTable;
const #8 = Asciz ForwardRefTest;
const #9 = class #8; // ForwardRefTest
const #10 = Asciz java/lang/Object;
const #11 = class #10; // java/lang/Object
const #12 = Asciz ()V;
const #13 = Asciz <init>;
const #14 = NameAndType #13:#12;// "<init>":()V
const #15 = Method #11.#14; // java/lang/Object."<init>":()V
const #16 = Asciz I;
const #17 = Asciz h;
const #18 = NameAndType #17:#16;// h:I
const #19 = Field #9.#18; // ForwardRefTest.h:I
const #20 = Asciz a;
const #21 = NameAndType #20:#16;// a:I
const #22 = Field #9.#21; // ForwardRefTest.a:I
const #23 = Asciz this;
const #24 = Asciz LForwardRefTest;;
const #25 = Asciz ForwardRefTest.java;
const #26 = Asciz D:\JavaDevelopment\Testing\ForumQuestions3\;
{
int h;
int a;
ForwardRefTest();
Code:
Stack=2, Locals=1, Args_size=1
0: aload_0
1: invokespecial #15; //Method java/lang/Object."<init>":()V
4: aload_0
5: aload_0
6: getfield #19; //Field h:I
9: putfield #22; //Field a:I
12: return
LineNumberTable:
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 13 0 this LForwardRefTest;
}
*/
Edited by NormR1: n/a
The current Language Reference has this to say:
8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.A compile-time error occurs if any of the four requirements above are not met.
What's interesting is that the third condition (via a simple name), which is the one that answers this question, was not present in earlier versions (eg JDK 1.4.2) of the same documentation. Did they change the language, or did they just notice this behaviour?
8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.A compile-time error occurs if any of the four requirements above are not met.
Thanks a lot. Can you please explain the 4th condition ?
Have a look at the language ref 8.3.2.3 - the bit I quoted is followed by loads of examples illustrating each of those points.
ive been develop a project known as ordering system
i need to delete data from db by clicking the button
ive follow a tutorial from utube and to the exact ...
Dear Friends,
Good Day,
I am facing an issue in one of the functions the code is given below if someone can help on this actually this function is supposed ...
There are a number of very old threads on CUDA so I'm starting a new one rather than resurrecting an old one.
Does anyone here have any experience setting up ...