java class initialize order, how it works? - java

package ali;
public class test {
public static int n = 99;
public static test t1 = new test("t1");
public static test t2 = new test("t2");
public static int i = 0;
public static int j = i;
{
System.out.println("construct block");
}
static {
System.out.println("static construct block");
}
public test(String str){
System.out.println((++j) + ":" + " i="+ i + " n="+n+str);
n++;i++;
}
public static void main(String [] args){
test test1 = new test("initl");
}
}
after running:
construct block
1: i=0 n=99t1
construct block
2: i=1 n=100t2
static construct block
construct block
1: i=0 n=101initl
Who can tell me how it works?
why there is no "static construct block" when t1 and t2 ware created?
why i and j changed to the default ,but n still unchanged?

static variables/blocks are executed/initialized as they appear (usually).
your output and why? :
When the class is loaded and during its initialization, the following lines will be executed
public static test t1 = new test("t1");
public static test t2 = new test("t2");
which in-turn create new Test objects, but since the class is already under initialization, the above lines are not executed again.
So,
you get
construct block
1: i=0 n=99t1
construct block
2: i=1 n=100t2
Next, the static block executes
static construct block
Now when you create an object of Test in main(), you will have
construct block
1: i=0 n=101initl

When this class (which really should have a capitalized name) is loaded, the static initializers are invoked in the order in which they appear in the source code. This means that the new test("t?") object creations happen before the explicit static block.

Related

Execution sequence of static, constructor and blocks in java [duplicate]

This question already has answers here:
Are fields initialized before constructor code is run in Java?
(5 answers)
Closed 2 years ago.
It's a Interview Question, manually write the output of code below:
public class StaticTest {
public static int k = 0;
public static StaticTest t1 = new StaticTest("t1");
public static StaticTest t2 = new StaticTest("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("Constructor Block");
}
static {
print("Static Block");
}
public StaticTest(String str) {
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
++i;
}
public static int print(String str) {
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
return ++n;
}
public static void main(String[] args) {
StaticTest t = new StaticTest("init");
}
}
Output:
1:j i=0 n=0
2:Constructor Block i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:Constructor Block i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:Static Block i=7 n=99
9:j i=8 n=100
10:Constructor Block i=9 n=101
11:init i=10 n=102
Very Confused why execute print first, which even starts with j?
I think static field and blocks are executed when class loading, so at least it should execute public static int i = print("i"); before public int j = print("j");.
JVM executes static blocks before the main method at the time loading a class.
And static block will execute only once when class gets loaded. But Instance Initialization blocks and Constructor will run every time object of a Class gets created.
Static initialization blocks are static and hence they belong to a particular class and not to the instances of class.Instance initialization blocks do not belong to a class and they are executed every time a new instance of the class is created.
When we execute above class, StaticTest class is loaded into JVM.
First thing it does is, executing all static blocks even before main() method gets executed .Thus the first 8 lines of your output will be executed even before your main method is triggered.
In the order of existence public static StaticTest t1 = new StaticTest("t1") will be executed after public static int k = 0.
As there is a new instance initialization,
Line 1 indicates the execution of public int j = print("j")
Line 2 indicates the execution of print("Constructor Block")
Line 3 indicates the execution of constructor StaticTest("t1") when creating object.
Instance Initialization blocks are executed whenever the class is initialized and before constructors are invoked . Thus print("Constructor Block") executed before the constructor. And print("j") precedes everything.
Like the above scenario public static StaticTest t2 = new StaticTest("t2") also follows the same execution flow which correspond to Line 4,5, and 6.
Then public static int i = print("i") which correspond to Line and 8.
Line 9 indicates the execution of public int j = print("j")
Line 10 indicates the execution of print("Constructor Block")
Line 11 indicates the execution of constructor StaticTest("init") when creating object.

Forward reference and recursion

Why is it possible for a variable to call (initialise itself) a method that calls the same variable (seems a recursion)? I expected to see an endless recursion, but it compiles without errors. Any explanation?
class Forward {
static int test(){
return i;
}
static int i=test();
public static void main(String[] args) {
System.out.println(test()); //sout= 0
System.out.println(i); //sout =0
}
}
Another example. Why does referencing Backwards.j work while referencing j gives an error("illegal forward reference"):
class Backwards{
//static int i=j; //illegal forward reference;
static int i=Backwards.j; //reference through class works
static int j=i;
public static void main(String[] args) {
System.out.println(i);
System.out.println(j);
}
}
If you step through the code in your debugger you will see that i = test(); is only run once ever.
The previous value for i is 0 and that's the value test() returns before i has been initialised.
The java compiler can't detect every possible forward reference, only the simplest ones.

Sequence of execution for variable creation and static block

class F
{
static
{
i = 1;
}
static int i = 2;
public static void main(String[] args)
{
System.out.println(i);
}
}
The output of this execution is 2. Can someone explain why not 1? In which sequence variables are getting created and initialized and static block is executed?
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
kindly check java documentation.
then clearly mentioned no matter how may static blocks are there they will be executed as a single block in the order they appear
So,
My understanding here is java is looking your code as
static{
i=1;
i=2;
}
static int i;
that is why you are getting output 2
hope this is helpful

Getting value to display for Java CurrentAccount class

package bankAccount;
public class CurrentAccount {
int account[];
int lastMove;
int startingBalance = 1000;
CurrentAccount() {
lastMove = 0;
account = new int[10];
}
public void deposit(int value) {
account[lastMove] = value;
lastMove++;
}
public void draw(int value) {
account[lastMove] = value;
lastMove++;
}
public int settlement() {
int result = 0;
for (int i=0; i<account.length; i++) {
result = result + account[i] + startingBalance;
System.out.println("Result = " + result);
}
return result;
}
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
}
}
At the moment, when I run the class, the expected System.out.println does not appear, and if I simply move public static void main(String[] args) to the top, this generates multiple red points. What is the best way for me to refactor my code so it works in the expected way?
you can have another class called Main in the file Main.java in which you can write your
public static void main(String args[])
and call
c.settlement();
in you main() to print.
Also one more advice,
in your constructor you have
account = new int[10];
which can hold only 10 ints.
in your deposit() and draw() you are not checking the account size. When the value of lastMove is more than 10 , the whole code blows up.
Hence I suggest you to use ArrayList
You never called the settlement method...
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
c.settlement();
}
I have the feeling that you come from some non-OOP language, like C or PHP. So some explanation:
The main method is static: that means it "exists" even when there is no object instance created, it can be thought of as if it belonged to the class instance.
on the contrary, for the other methods to "work", an instance is required.
This way the main method can be (and is actually) used as the entry point of the application
It is executed, and when it exists, (if no other threads are left running) the application terminates.
so nothing else is run that is outside of this method just by itself...
so if you don't call c.settlement(); - it won't happen...
Other notes:
Running main doesn't create an instance of the enclosing class
with new CurrentAccount(), you create an object instance, which has states it stores, and can be manipulated
be careful with arrays, they have to be taken care of, which tends to be inconvenient at times...
Why do you expect the printed output to appear? You don't actually call the settlement method, so that command is not executed.
You did not call settlement.. so nothing appears
if you add c.settlement... it is fine..
You have not called deposit() and settlement() in the main method untill you call, You cannot get expected output.

Null Pointer Exception in JUnit test

Whenever I try to test my code with JUnit, I receive a NullPointerException - even though I don't get that exception when I run the actual program. The line that gives me the exception is:
assertEquals(0.0, TweetClassification.tweetType[TweetClassification.SIGNIF_OTHER].likelihoodA);
The beginning of the TweetClassification class it's testing is as follows:
public class TweetClassification
{
// CONSTANTS =============================================
public static final int TCNUMBER = 5; // number of TweetCategories (including the null category)
// using constants to indicate the names of the TweetCategories, so that they could be renumbered
public static final int NULLTWEET = 0;
public static final int SIGNIF_OTHER = 1;
public static final int FRIENDS = 2;
public static final int WORK = 3;
public static final int FOOD = 4;
public static final TweetCategory[] tweetType = new TweetCategory[TCNUMBER];
...
(TweetCategory is another class that is defined separately within the package.) So I realize that this code initializes the array but not its members, and that's probably why I'm getting the exception(?) But the thing is, I do initialize the members of the array within the main method of TweetClassification, as follows:
for (int i=0; i<TCNUMBER; i++)
{
tweetType[i] = new TweetCategory();
}
But if I try to move this for loop outside the main method with the constants I get a syntax error - I presume you're not supposed to use a for loop outside of a method. So I'm not sure how to initialize the class properly for JUnit to work - either I do it outside the main method and get a syntax error, or I do it inside the main method and get a NullPointerException. Any ideas?
You need to move the init code into a static initializer block, like this:
public class TweetClassification
{
//...
public static final TweetCategory[] tweetType = new TweetCategory[TCNUMBER];
static
{
for (int i=0; i<TCNUMBER; i++)
{
tweetType[i] = new TweetCategory();
}
}
//...
}
This ensures that the static variable is initialized properly when the class is loaded (i.e. before it is first used anywhere within your program or tests).
Yo might find some use of the static initialzier block:
private static Integer arr[] = new Integer[2];
static {
for (int i = 0; i < 2; i++) {
arr[i] = 2;
}
}
public static void main(String[] args) {
System.out.println(arr[1]);
}
Ouputs:
2
This is proper java and is meant exactly for initializing static variables, though it is not very commonly used.

Categories