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.
Related
I encountered this problem when doing a question on LeetCode: https://leetcode.com/problems/print-in-order/
Consider two submissions:
1.
class Foo {
private static int signal = 0;
public Foo() {}
public synchronized void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
signal += 1;
notifyAll();
}
public synchronized void second(Runnable printSecond) throws InterruptedException {
while(signal != 1)
wait();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
signal += 1;
notifyAll();
}
public synchronized void third(Runnable printThird) throws InterruptedException {
while(signal != 2)
wait();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
notifyAll();
}
}
2.
class Foo {
private static int signal = 0;
public Foo() {signal = 0;}
public synchronized void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
signal += 1;
notifyAll();
}
public synchronized void second(Runnable printSecond) throws InterruptedException {
while(signal != 1)
wait();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
signal += 1;
notifyAll();
}
public synchronized void third(Runnable printThird) throws InterruptedException {
while(signal != 2)
wait();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
notifyAll();
}
}
Try submitting these two and you'll find submission 1 will result in Time Limit Exceeded while submission 2 will be accepted.
The only difference is that in submission 2, I explicitly added a statement signal = 0; to initialize the static variable. It should play no difference as I have already given this variable a default value in private static int signal = 0;, so what is going on here. Is there any subtleties in the static field initialization in Java that I did not know?
Thank you very much.
LeetCode runs several different test cases against your solution. Let's assume that LeetCode is running a single JVM and running all the test cases in that JVM, but it is instantiating a new Foo for each case.
When running the first case, signal is zero, and your code works as expected. But at the end of this test case signal is now 2, because the test case increments it twice. Since it is static, it is shared among all instances of Foo. Even though LeetCode instantiates a new Foo for the second test case, the static signal is still 2. The first method increments it to 3, but then the test hangs because the condition while (signal != 1) is always true.
Initializing signal to 0 in the Foo constructor has the effect of resetting signal before the second and subsequent test runs.
There's no reason to make signal static here. It should be a regular non-static member so that each instance of Foo gets a new signal initialized to zero.
I am trying to print the number increment by 1 whenever i call the function, but i am not able to get the solution, below is my code
The blow is the function
public class Functions<var> {
int i=0;
public int value()
{
i++;
return i;
}
}
I am calling the above function here
import Java.Functions;
public class Increment {
public static void main(String[] args)
{
Functions EF = new Functions();
System.out.println(EF.value());
}
}
Whenever i run the program , i am getting only the output as 1 , but i want the output to be incremented by 1 . Could you please help. Thanks in Advance.
I believe your answer is with the scope of your variables and your understanding of them. You only call the method once in your given examples, so 1 is arguably the correct answer anyway. Below is a working example which will persist during runtime one variable and increment it every time a function is called. Your methods don't seem to follow the common Java patterns, so I'd recommend looking up some small example Hello, World snippets.
public class Example{
int persistedValue = 0; // Defined outside the scope of the method
public int increment(){
persistedValue++; // Increment the value by 1
return persistedValue; // Return the value of which you currently hold
// return persistedValue++;
}
}
This is due to the scope of "persistedValue". It exists within the class "Example" and so long as you hold that instance of "Example", it will hold a true value to your incremented value.
Test bases as follows:
public class TestBases {
static Example e; // Define the custom made class "Example"
public static void main(String[] args) {
e = new Example(); // Initialize "Example" with an instance of said class
System.out.println(e.increment()); // 1
System.out.println(e.increment()); // 2
System.out.println(e.increment()); // 3
}
}
If your desire is out of runtime persistence (the value persisting between application runs) then it would be best to investigate some method of file system saving (especially if this is for your Java practice!)
Your main problem is to increment the number value 1.
But you are calling your function only once. Even though you call the function many times you will get the value 1 only because it is not static variable so it will every time initialize to 0.
So please check below answer using static context.
Functions.java
public class Functions{
static int i=0;
public int value()
{
i++;
return i;
}
}
Increment.java
public class Increment{
public static void main(String []args){
Functions EF = new Functions();
System.out.println(EF.value());
System.out.println(EF.value());
System.out.println(EF.value());
}
}
Output:
1
2
3
If you design multi-threaded application, it will be better to use AtomicInteger.
The AtomicInteger class provides you an int variable which can be read and written atomically.
AtomicInteger atomicInteger = new AtomicInteger();
atomicInteger.incrementAndGet();
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
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.
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.