Reputation: 6892
P.S :
This question has been edited a few times as my previous code doesn't demonstrate the problem. There are some answers which may not make perfect sense against the edited question
I have a public class named Son.java
package com.t;
public class Son extends Father {
static int i;
static {
System.out.println("son - static");
i = 19;
}
{
System.out.println("son - init-block");
}
public static void main(String[] args) {
//Son s = new Son();
int a[] = new int[2];
System.out.println(a[5]);
}
}
class Father {
static {
System.out.println("f - static");
}
{
System.out.println("f - init-block");
}
}
When I run the program for the 1st time:
Output is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.t.Son.main(Son.java:19)
f - static
son - static
And later when I run this program (order of output is random
)
Output is:
f - static
son - static
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.t.Son.main(Son.java:19)
I have read that static
blocks are executed as the classes are initalised.
But why does the exception has come first here and then static block is executed?
I am using Eclipse
too to run my program.
Can somebody explain?
Upvotes: 4
Views: 222
Reputation: 1225
As the asker said main
belongs to Son
class and is extending Father
. I modified the code a little, so I was able to compile.
class Father {
static{
System.out.println("f - static");
}
}
public class Son extends Father {
static {
System.out.println("son - static");
}
public static void main(String[] args) throws ArrayIndexOutOfBoundsException{
int a[] = new int[2];
System.out.println(a[3]);
}
}
And the output is:-
f - static
son - static
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at kanwal.Son.main(Son.java:20)
Its working exactly, the way it is supposed to.
EDIT:- This answer was made, before OP edited the question.
Upvotes: -2
Reputation: 718678
@Keppil's answer has nailed it.
I just want to point out something ... erm ... interesting.
The OP says this:
I am using Eclipse to run my program.
The knee jerk response would be to say "that isn't relevant" ... but in this case, I think it >>is<< relevant. I suspect that non-determinism in stdout/stderr timing is being is amplified by the fact that the output is going to a Eclipse "console" panel.
When an application is run from the command line, output to stderr and stdout probably gets merged into out stream somewhere in the OS kernel. And if not, the console program probably uses a select
syscall to handle input from two sources ... and gives one stream priority over the other, 'cos that is the easy way to code it. As a result, you would expect the output to appear on the console in a mostly consistent order, even though order is non-deterministic.
But when the application writes to an Eclipse console, Eclipse probably uses a separate thread to read each stream. Assuming that both threads are blocked in read
syscalls, and input arrives at roughly the same time on both streams, it will be up to the thread scheduler to decide which thread gets woken first. That is going to be far less predictable that the behaviour of a select ... or of stream merging in the kernel.
Either way, my observation is that reordered stdout / stderr output is more prevalent with an Eclipse console than when you are using a "native" console.
Upvotes: 0
Reputation: 46209
The exception doesn't happen first, you are just seeing the printout of the exception first.
Had the exception happened first, you would never have seen the rest of the output.
The reason for this is that you have output to both System.err
(from your exception) and System.out
in your program. The order in which these are printed to the screen is not defined, so therefore you can get them in different order.
Upvotes: 10
Reputation: 31269
Stack traces of uncaught exceptions are printed in System.err
, which is an unbuffered stream. You print text to System.out
which is a buffered stream and it is unpredictable whether it he buffer gets flushed before or after the stack trace is printed.
If you change all your print statements to System.err
then the order of the output will become the order of printing, and it will always be the same order.
Upvotes: 3