-
Bug
-
Resolution: Fixed
-
P4
-
8
FULL PRODUCT VERSION :
not important
ADDITIONAL OS VERSION INFORMATION :
not important
EXTRA RELEVANT SYSTEM CONFIGURATION :
not important
A DESCRIPTION OF THE PROBLEM :
package net.octoplar;
/**
* Created by Octoplar on 05.10.2016.
*/
//This program output is
//1
//1
//2
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
/*https://docs.oracle.com/javase/specs/jls/se8/html/ */
/*According point 15.28
* expression 'C.j+C.k' is constant expression, because it composed using:
* C.j - Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).
* + - The additive operators + and - (§15.18)
* C.k - Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).
*
* expression '1' is constant expression, because it composed using:
* 1 - Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)
*
* expression 'i+j' is constant expression, because it composed using:
* i - Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
* + - The additive operators + and - (§15.18)
* j - Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
*
* According point 4.12.4
* i, j, k is constant variables
* A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
* Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1),
* binary compatibility (§13.1, §13.4.9), and definite assignment (§16 (Definite Assignment)).
*
*
*
* According point 8.3.2
* i, j, k is static fields that are constant variables
* Note that static fields that are constant variables (§4.12.4) are initialized before other static fields (§12.4.2).
* This also applies in interfaces (§9.3.1).
* Such fields will never be observed to have their default initial values (§4.12.5), even by devious programs.
*
* But in this example program observe k(static field that are constant variable) in two states:
* default initial value 0 at "static final int i=C.j+C.k;"
* and initial value 2 at "System.out.println(k);"
* */
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run this:
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect no results.
I learn JLS now and i find this bug.
ACTUAL -
1
1
2
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1. remove from JLS 8.3.2 words "Such fields will never be observed to have their default initial values (§4.12.5), even by devious programs." because it is not true.
2. Forbid all types forward references during field initialization. Now forbidden ornly direct forwadr reference. Example:
class B {
//Instance variable forward reference example
int iv1= iv; // error. Illegal forward reference
int iv2=this.iv; //this is too forward reference, but all OK
B selfRef=this;
int iv3=selfRef.iv; //this is too forward reference, but all OK
//Class variable forward reference example
static int cv1 =cv; //error. Illegal forward reference
static int cv2 =B.cv; //this is too forward reference, but all OK
int iv =11;
static int cv=22;
}
not important
ADDITIONAL OS VERSION INFORMATION :
not important
EXTRA RELEVANT SYSTEM CONFIGURATION :
not important
A DESCRIPTION OF THE PROBLEM :
package net.octoplar;
/**
* Created by Octoplar on 05.10.2016.
*/
//This program output is
//1
//1
//2
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
/*https://docs.oracle.com/javase/specs/jls/se8/html/ */
/*According point 15.28
* expression 'C.j+C.k' is constant expression, because it composed using:
* C.j - Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).
* + - The additive operators + and - (§15.18)
* C.k - Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).
*
* expression '1' is constant expression, because it composed using:
* 1 - Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)
*
* expression 'i+j' is constant expression, because it composed using:
* i - Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
* + - The additive operators + and - (§15.18)
* j - Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
*
* According point 4.12.4
* i, j, k is constant variables
* A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
* Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1),
* binary compatibility (§13.1, §13.4.9), and definite assignment (§16 (Definite Assignment)).
*
*
*
* According point 8.3.2
* i, j, k is static fields that are constant variables
* Note that static fields that are constant variables (§4.12.4) are initialized before other static fields (§12.4.2).
* This also applies in interfaces (§9.3.1).
* Such fields will never be observed to have their default initial values (§4.12.5), even by devious programs.
*
* But in this example program observe k(static field that are constant variable) in two states:
* default initial value 0 at "static final int i=C.j+C.k;"
* and initial value 2 at "System.out.println(k);"
* */
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run this:
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect no results.
I learn JLS now and i find this bug.
ACTUAL -
1
1
2
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class C {
static final int i=C.j+C.k; // "static field that are constant variable" k have default initial value here. This is JLS violation
static final int j=1;
static final int k=i+j;
public static void main(String[] args) {
System.out.println(i); //1
System.out.println(j); //1
System.out.println(k); //2
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1. remove from JLS 8.3.2 words "Such fields will never be observed to have their default initial values (§4.12.5), even by devious programs." because it is not true.
2. Forbid all types forward references during field initialization. Now forbidden ornly direct forwadr reference. Example:
class B {
//Instance variable forward reference example
int iv1= iv; // error. Illegal forward reference
int iv2=this.iv; //this is too forward reference, but all OK
B selfRef=this;
int iv3=selfRef.iv; //this is too forward reference, but all OK
//Class variable forward reference example
static int cv1 =cv; //error. Illegal forward reference
static int cv2 =B.cv; //this is too forward reference, but all OK
int iv =11;
static int cv=22;
}
- relates to
-
JDK-8204693 8.3.3: Disallow forward reference to a field by a qualified name using 'this'
-
- Open
-
-
JDK-8025762 8.3.3: Clarify that a field cannot be referenced in its own initializer
-
- Closed
-