What is RIWO (Read Indirectly Write Out) state - java

I was reading about the static flow control and came across the RIWO concept. Can someone explain this with simple terminology and perhaps a code sample?
This is related to the error "Illegal forward reference".
Relevant link.

After going through some material and discussing with couple of guys offline i found out the following information.
When a java class is getting executed there are few steps which JVM performs few steps sequentially.
Identify the static members from top to bottom.
Executes static variables assignments and static blocks from top to bottom.
Executes the main method.
During these phases there is one such state called RIWO(Read Indirectly Write Only) for a static variable.
During RIWO a variable cannot be accessed directly with its reference. Instead we need to use an indirect way to call certain variables.
for example:
class Riwo
{
static int i = 10;
static
{
System.out.println(i);
}
}
In the above case the output is 10.
class Riwo {
static int i = 10;
static {
m1();
System.out.println("block1");
}
public static void main(String... args) {
m1();
System.out.println("block main");
}
public static void m1() {
System.out.println(j);
System.out.println("block m1");
}
static int j = 20;
static {
System.out.println("end of code");
}
}
In the above case the output is
0
block m1
block1
end of code
20
block m1
block main
class Riwo
{
static
{
System.out.println(i);
System.out.println("block1");
}
static int i = 10;
public static void main(String... args)
{
System.out.println("main block");
}
}
In the above case we get the following compile time error
Riwo.java:5: illegal forward reference
System.out.println(i);
That means we cannot read a static variable directly when it is in RIWO state.We should call the variable indirectly using a method.

Static variable have two states
RIWO (Read Indirectly Write Only)
RW(Read Write).
RIWO:
Before assigning original value to static variable, variable state is called as RIWO state.
RW:
After assigning original value to static variable, variable state is called as RW state.
Static variable have two type of reading
Direct Read
InDirect Read
Direct Read:
Reading static variable from static block directly is called direct reading.
InDirect Reading:
Reading static variable from static block by calling another method is called indirect reading.
Direct Read Example:
Note: when static variable in RIWO state we cant perform Direct Reading.
class DirectReadingExample{
static {
System.out.println("i==="+i);
}
//i is in RIWO state
static int i=100;
//i is in RW State
}
Output:
compile time Error:illegal forward reference.
InDirect Read Example:
Note: when static variable in RIWO state we can perform InDirect Reading.
class InDirectReadingExample{
static {
m1();
}
static m1(){
System.out.println("i===="+i);
}
//i is in RIWO state
static int i=100;
//i is in RW State
}
Output:
i===0

If a variable is just identified by JVM and the original value is not
yet assigned, then the variable is said to be in the RIWO(Read Indirectly Write Only) state.
The following code is legal:
class Test{
static int num=10;
static
{
System.out.print(num);
System.exit(0);
}
}
output:
10
The code below will produce a compile time error(illegal forward reference)
class Test{
static
{
System.out.print(num);
}
static int num=10;
}
//Produces Compile time error
The code below is legal:
class Test{
static
{
int x=readVar();
}
static int readVar(){
System.out.println(num);
return 0;
}
static int num=10;
static
{
System.out.print(num);
}
}
output:
0
10
In this case, we're not performing a direct read, but rather an indirect
read via a method call. The variable num is identified by JVM - step 1.
Then the default value 0 is assigned to num at that time.

Related

Can i initialize static variable after the initialization?

What is the problem with below code?
class test {
static int a;
a=10;
}
If I'm writing like this (as above), I'm getting a compile time error.
class test {
static int a=10;
a=4;
}
For the second one, I'm not getting any error.
Neither of your examples should compile.
a=10;
is a statement, which is not valid directly inside a class declaration. You can only put the following directly inside a class:
Member declarations (member/static variable declarations (like static int a;), methods, nested classes and interfaces);
Static and instance initializers;
Constructors.
You need to put a statement inside a block, for example a static initializer:
static int a;
static {
a = 10;
}
which is equivalent to:
static int a = 10;
You need to use a static block of statement to do an assignment on an other line (outside a method)
class test {
static int a;
static { a=10; }
}
a=4; must be done in a valid scope
either a method or a constructor...
this line is valid instead
static int a=10;
because java allows youto declare and initialize in one statement!
If you want to initialize a after defining it as a null int, you can only do that in a function, because it is static.
must be initialized inside static block or init block or in constructor.
you can only initialized your member variable after declaration inside a function or block because it is static you should use static block
What you are currently doing is declaring a variable in a class decleration, which is not valid. Looking at this neither of your examples should give you any good result.
In a class declaration you can however initialize a variable:
static int a;
Then if you want to work with it you would have to create a method first (if you are not aware of this I would strongly advise to watch some youtube tutorials or read books about this topic) :
public void foo(int a){
a = 6; //Here you can play with your variables and change them
}
In class declararions you can: declarations methods, initializers and constructors. (there is a bit more you can do, however I would have a look at these points before diving in too deep).
Furthermore it seems that you are not aware what a static variable or a static method does, I think the following posts will help you with that:
difference between 'static int' and 'int' in java
What are static method and variables?
I hope I could help and have fun learning Java
Because for static memory allocated at the time of class loading
so we need do like this
class test {static int a =10;
public static void main(String args[]) { a=12 output(test.a (or) a);}}
A Java class body is should contain declarations and declaration with an initializer, not the standalone statements. Let's unwrap your requirement of initializing a static variable.
Static variables should not be initialized inside methods as these variables belong to the class. But they can be initiated inside the constructor.
public class Example {
static String name;
static int age;
Example() {
name = "James";
age = 34;
}
public static void main(String args[]) {
new Example();
System.out.println(Example.name);
System.out.println(Example.age);
}
}
Now the output will be :
James
34
If new Example(); is not called then the output will be :
null
0
This is because the static variables are initialized with an object creation and for each Example object name and age will be overwritten with the same value. But at least one object needs to be created for name and age to be initialized.
But if you declare a static and final instance variable, we cannot initialize that in the constructor, it is mandatory to initialize static and final variables at the class level. We can initialize while declaring the variable or using a static initialization block. This runs before the main() method in Java. Hence when the main() method is loaded this static variable will be initialized and the compiler will not throw any errors.
static final int name = "STRING";
static final int age;
static {
age = 10;
}
Putting all these things together,
A static variable can be initialized,
When declaring.
Inside a constructor.
Inside a static block.
A static final variable can be initialized,
When declaring.
Inside a static block.
A final variable can be initialized,
When declaring.
Inside a constructor (If you have more than one constructor in your class then it must be initialized in all of them).

Why an instance variable can be assigned and not be referenced before its declaration in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java static class initialization
in what order are static blocks and static variables in a class executed?
When I run this code the answer is 1, I thought it would be 2.
What is the order of initialization and the value of k in each step?
public class Test {
static {k = 2;}
static int k = 1;
public static void main(String[] args) {
System.out.println(k);
}
}
Edit 1: As a follow up to "k is set to default value" then why this next code doesn't compile? Theres an error "Cannot reference a field before it's defined".
public class Test {
static {System.out.println(k);}
static int k=1;
public static void main(String[] args) {
System.out.println(k);
}
}
Edit 2: For some unknow to me reason it^ works when instead of "k" its "Test.k".
Thanks for all the answers. this will sufice :D
They are executed in the order that you write them. If the code is:
public class Test {
static int k = 1;
static {k = 2;}
public static void main(String[] args) {
System.out.println(k);
}
}
then the output becomes 2.
The order of initialization is: ..the class variable initializers and static initializers of the class..., in textual order, as though they were a single block.
And the values (for your code) are: k = 0 (default), then it's set to 2, then it's set back to 1.
You can check that it's actually set to 2 by running the following code:
private static class Test {
static {
System.out.println(Test.k);
k = 2;
System.out.println(Test.k);
}
static int k = 1;
public static void main(String[] args) {
System.out.println(k);
}
}
Short answer
When the initialization of the class starts, k will have initial value of 0.
The static block (since it precedes the assignment in the declaration) is then executed, and k will be assigned 2.
Then the initializer in the declaration is executed, and k will be assigned 1.
Long explanation
Let us use this example, since your example is a bit simple:
class TestInitOrder {
static {
System.out.println(TestInitOrder.stat1);
System.out.println(TestInitOrder.stat2);
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.str2);
str = "something";
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.str2);
System.out.println(TestInitOrder.lazy);
System.out.println(TestInitOrder.second);
}
private static final int stat1 = 10;
static final String str2 = "sdfff";
static String str = "crap";
private static int stat2 = 19;
static final Second second = new Second();
static final int lazy;
static {
lazy = 20;
}
static {
System.out.println(TestInitOrder.str2);
System.out.println(TestInitOrder.stat2);
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.lazy);
System.out.println(TestInitOrder.second);
}
public static void main(String args[]) {
}
}
class Second {
public Second() {
System.out.println(TestInitOrder.second);
}
}
According to Java Language Specification, from section 4.12.5:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created
(The following lines from the specification specify the default value for all the types, basically some form of 0, such as 0, 0.0d, null, false, etc.)
So before the class is initialized (due to one of these reasons), the variables will hold an initial value.
According to the detailed initialization procedure (only the interesting steps are quoted here, and emphasis mine):
6.
[...] Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).
[...]
9.
Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
Let us look at step 6, with the 4 final class variables: stat1, str2, second, lazy.
Since 10 is constant expression, and so is "sdfff", and due to the order of execution, it is not possible to observe the initial value for str2 and stat1. In order to make an observation, the earliest you can do is in step 9.
The case of second demonstrate that when the right hand side is not a compile-time constant expression, so its initial value is visible.
The case of lazy is different, since the assignment is done in static block, and hence happen in step 9 - so it is possible to observe its initial value. (Well, the compiler checks carefully that lazy is assigned exactly once).
After the initialization of final class variables with compile-time constant expression comes the execution of static blocks and the rest of the initializers.
As you can see from the example, the static blocks and initialization happens according to textual order - demonstrated with the use of str variable - it is first printed out as null, then something, then crap.

Loose blocks of code

When I try running this piece of code, it prints "x y c g ". I know that x has priority over y because it is static and the constructor (c) prints before the method (g), but what exactly is the purpose of putting two lines in their own blocks, and what does this help achieve?
public class Sequence {
Sequence() { System.out.print("c "); }
{ System.out.print("y ");}
public static void main(String[] args) {
new Sequence().go();
}
void go() { System.out.print("g "); }
static { System.out.print("x "); }
}
Your question is closely related to this one, but not exactly a duplicate: Why java Instance initializers?
When you first reference a class, it gets loaded and the static components get initialized in the static initializer. These blocks can be very useful, for setting up collections or loading native code.
An instance initializer is a bit of code that works similar to the static initializer except it operates on every instance before the constructor is invoked. It appears that there is no absolute need for this in Java since it can just be placed in the beginning of your constructor.

Difference between static declaration and non static declaration

Static variables: Are the class variables and they are not created separately for each object of the class.
Instance variables: Are also the class variables but are created for each object separately.
The above definitions are just for references.
Please explain why i am getting error in this class declaration.I know it is just because i have not of initialised x.
class non_static{
public static void main(String args[])
{
int x;
System.out.println(x);
}
}
But this class declaration is totally fine.
class static_example{
static int x;
public static void main(String args[])
{
System.out.println(x);
}
}
And output of this program is 0.
Please do explain me why static member is initialized with the default value while local variables are not.
It has nothing to do with static declaration vs instance declaration. It is local declaration, which does not have a default and will cause an error when it is used uninitialized.
public class Example {
private static int stattic;
private int instancee;
public void someMethod() {
System.out.println("I am static and 0: " + stattic);
System.out.println("I am not static and 0: " + instancee);
int locall;
System.out.println("I am causing an error because I have not been initialized: " + locall);
}
}
If you want to know the background on why Java specifies it like that, it has to do wih the limits of static code analysis. Memory allocated from the stack (and this is where the local vars are) can be confirmed positively by the compiler to be initialized before use. Not so with heap-allocated storage (static vars, instance vars). This is why the JLS requires the implementations to always zero out any heap storage before exposing a pointer to it.
Local variables must always be initialized with a value. For non-local variables (i.e. instance or static variables) the default is defined as the corresponding type's null values (null, zero or false).
In java the Instance Variables (ie class variables) are initialized to their default values.
But the Local Variables (ie Method variables) CAN NOT be used without initializing...
class static_example{
static int x;
public static void main(String args[])
{
System.out.println(x);
}
}
In the above example of yours, x is declared at Class scope... So it is already initialized to its default value 0, so its NOT GIVING any error..

Why is this Java code in curly braces ({}) outside of a method?

I am getting ready for a java certification exam and I have seen code LIKE this in one of the practice tests:
class Foo {
int x = 1;
public static void main(String [] args) {
int x = 2;
Foo f = new Foo();
f.whatever();
}
{ x += x; } // <-- what's up with this?
void whatever() {
++x;
System.out.println(x);
}
}
My question is ... Is it valid to write code in curly braces outside a method? What are the effects of these (if any)?
Borrowed from here -
Normally, you would put code to initialize an instance variable in a
constructor. There are two alternatives to using a constructor to
initialize instance variables: initializer blocks and final methods.
Initializer blocks for instance variables look just like static
initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
You may also wanna look at the discussions here.
This is an initializer block that is executed while the instance of the class is being loaded/created and that is used to initialize member properties of a class (See Java http://download.oracle.com/javase/tutorial/java/javaOO/initial.html). You can have as many blocks as you want and they will be instantiated from top to bottom.
In addition to the instance block, you can have as many static blocks as you want as well to initialize static members. They would be declared as follows:
public class Initialization {
static int b = 10;
int a = 5;
static {
b = -9;
}
{
a += 2;
}
public static void main(String[] args) throws Exception {
System.out.println(ClientVoting.b);
System.out.println(new ClientVoting().a);
System.out.println(ClientVoting.b);
System.out.println(new ClientVoting().a);
}
static {
b = 1;
}
{
a++;
}
}
While the class is being initialized, the static member "b" is initialized as 10, then the first static scope changes its value to -9, and later to 1. This is only executed once while the class is loaded. This executes before the initialization of the first line of the main method.
On the other hand, the similar example to your class is the instance reference "a". A is initialized as 5, then the instance block updates it to 7, and the last block to 8. As expected, the static members are only initialized once in this code, while the instance blocks are executed EVERY time you create a new instance.
The output to this example is 1 8 1 8
It's an initializer block. It's used to set instance variables. The motivation to use initializer blocks over constructors is to prevent writing redundant code. The Java compiler copies the contents of the block into each constructor.

Categories