Page 1 of 2

About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Nov 21, 2013 12:20 pm
by Zoryanat
Hi There
Please help me understand why this code compile at all - I mean, shouldn't this line below trigger compilation error -
static int[] x = new int[0];

Many thanks
Regards
Zoryana

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Nov 21, 2013 12:33 pm
by admin
Sure, but can you tell me why you think it should not compile so that I can address the cause of the doubt?

This is just Java language syntax. There is nothing much going on here except that you are declaring x as an array of int, and on the right hand side you are creating an array of ints of size 0.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Nov 21, 2013 12:40 pm
by Zoryanat
I see. Well I thought it was not possible to create it this way :D But then, String[] args in main is array of size 0, if nothing is passed to main... So this is just a way to declare it then? just say "new int[0]"?

Rds
Zoryana

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Nov 21, 2013 12:45 pm
by admin
Zoryanat wrote:So this is just a way to declare it then? just say "new int[0]"?
Yes, that's the way to define an int array of 0 length. You can define any array of 0 length this way i.e. new String[0] or new Object[0];

You can also do: new int[]{ };//size will be interpreted from the number of elements within { }.

but not: new int[0]{ }; //this is invalid.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Nov 21, 2013 12:50 pm
by Zoryanat
great, thanks very much. That's me sorted :))

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Sep 04, 2014 9:23 am
by Nisim123
Yes, that's the way to define an int array of 0 length. You can define any array of 0 length this way i.e. new String[0] or new Object[0];

You can also do: new int[]{ };//size will be interpreted from the number of elements within { }.

but not: new int[0]{ }; //this is invalid.
So what is the difference between what you say that you can define an array this way: new String[0] or
new Object[0] and between what the question asks:

static int[] x = new int[0]; ?

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Sep 04, 2014 12:32 pm
by admin
None.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Wed Sep 10, 2014 8:06 am
by Nisim123
Sorry if I was misunderstood or making an impact of being upset,
it is just that in question :enthuware.ocajp.i.v7.2.1326

There is a similar case that causes actually a RuntimeException.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Wed Sep 10, 2014 8:23 am
by admin
Please post the exact code you are having trouble understanding and also mention which part is causing the trouble so that we can help you better.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Sep 11, 2014 9:19 am
by Nisim123
Ok, thanks for making me being more exact in what i find hard to settle.

you were answering Zoryanat explaining possible ways of declaring an array:
Yes, that's the way to define an int array of 0 length. You can define any array of 0 length this way i.e. new String[0] or new Object[0];

You can also do: new int[]{ };//size will be interpreted from the number of elements within { }.

but not: new int[0]{ }; //this is invalid.

Then i've brought an example from question enthuware.ocajp.i.v7.2.1326

that actually proves that you cannot declare an array this way.

enthuware.ocajp.i.v7.2.1326 asks:
What will happen when the following code is compiled and run?
class AX {
  static int[] x = new int[0];  
static {    x[0] = 10;   }  
 public static void main(String[] args){    
 AX ax = new AX();   
}
}
Then the right option selected for this question is:
It will throw ExceptionInInitializerError at runtime.
followed by the explanation:
The following is the output when the program is run:
java.lang.ExceptionInInitializerError Caused by:
java.lang.ArrayIndexOutOfBoundsException: 0        
 at AX.<clinit>(SM.java:6)
Exception in thread "main" Java Result: 1

Note that the program ends with ExceptionInInitializerError
because any exception thrown in a static block is wrapped into ExceptionInInitializerError
and then that ExceptionInInitializerError is thrown.

so what i wanted to say is that this kind of array declaration might not work,
as opposed to the explanation that was given to Zoryanat above.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu Sep 11, 2014 10:57 am
by admin
I don't see any contradiction in the explanation given to Zoryanat and the explanation that you've quoted.
When you say, "might not work", what exactly do you mean by "work"? Do you mean will not compile or will not run? and what part exactly do you think will not work?

-Paul.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sun Apr 05, 2015 12:42 pm
by ElizabethCM
Hello,

I have read that static initialization blocks are run first. Can you please explain me what happens when running the code in this related question?
Which one of the following two:
- static int[] x = new int[0];
and
- static{
x[0] = 10;
}
is evaluated first?

Can someone explain the order in which Java evaluates the two?

I hope you guys can understand my question:
I know that the static initializations are evaluated in the same order as they're declared. I have tried to put the above lines backwards and I have seen that it does not compile. Does this mean they have the same priority when the program runs? The static variable initializations and static blocks? They're just evaluated first when a program runs, in the order they are declared?

Thanks

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sun Apr 05, 2015 9:44 pm
by admin
The order of initialization of a class is:
1. All static constants, variables and blocks.(Among themselves the order is the order in which they appear in the code.)
2. All non static constants, variables and blocks.(Among themselves the order is the order in which they appear in the code.)
3. Constructor.

If you put the two statements in reverse order, then the rule about forward reference of class fields applies. This is given in section 8.3.3 of JLS. You are trying to use the variable before it is declared.

Please run the code with the changes and see what the compiler message says.
HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Wed Jul 29, 2015 9:52 am
by Sergiy Romankov
Hallo, I found a mistake

any exception thrown in a static block is wrapped into ExceptionInInitializerError

Not any exception but only Runtime Exceptions

Thanks, for your work.
Sergey

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Wed Jul 29, 2015 10:02 am
by Sergiy Romankov
if there is checked Exception in static block we will get compilation error

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Wed Jul 29, 2015 10:32 am
by admin
Sergiy Romankov wrote:Hallo, I found a mistake

any exception thrown in a static block is wrapped into ExceptionInInitializerError

Not any exception but only Runtime Exceptions

Thanks, for your work.
Sergey
It is not a mistake. It says "any exception thrown", which means it is talking about exceptions that can be thrown in the first place. But I agree that it would be good to add this information in the explanation to make it clear.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sun May 08, 2016 8:47 am
by Ingvarr
The explanation says: "If you try to throw a checked exception from a static or instance initializer block to the outside, the code will not compile."
That much is true.
However, by talking about *checked* exceptions, the sentence seems to imply (at least, in my eyes) that it is permissible to throw an RTE, as in the following code:

class Class{
static { throw new RuntimeException(); } // is to be commented out to make the next statement reachable
{ throw new RuntimeException(); }
}

The compiler isn't happy with that, either; it still wants the initializer "be able to complete normally." IMHO, the wording should be changed to reflect the fact that no exceptions at all may be thrown from an initializer block, be it static or otherwise, to the outside deliberately.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sun May 08, 2016 12:08 pm
by admin
Ingvarr wrote:However, by talking about *checked* exceptions, the sentence seems to imply (at least, in my eyes) that it is permissible to throw an RTE, as in the following code:

class Class{
static { throw new RuntimeException(); } // is to be commented out to make the next statement reachable
{ throw new RuntimeException(); }
}

The compiler isn't happy with that, either; it still wants the initializer "be able to complete normally." IMHO, the wording should be changed to reflect the fact that no exceptions at all may be thrown from an initializer block, be it static or otherwise, to the outside deliberately.
No, that is not correct. The following compiles fine:

Code: Select all

static { 
  if(someCondition) throw new RuntimeException();  //compiles
}
and the following doesn't:

Code: Select all

static { 
  if(someCondition) throw new Exception(); //does not compile
}
It is true that the code that you've given doesn't compile. But the reason that you gave for that is incorrect. The problem is not that the code is throwing an exception "deliberately". The problem is that the code *always* throws an exception. If the static (or instance) initialiser always throws an exception, you can't load a class at all (or create objects of it). The situation is similar situation to "unreachable code". That is why the compiler refuses to compile.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Mon May 09, 2016 10:22 am
by Ingvarr
admin wrote: If the static (or instance) initialiser always throws an exception, you can't load a class at all (or create objects of it). The situation is similar situation to "unreachable code". That is why the compiler refuses to compile.
Ah! I see the light now :) Thanks!

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sat Mar 25, 2017 5:49 am
by mjmsausava
Just to be sure.. the following program will throw exception because the array did not exist when the static block ran?

class AX{
static int[] x = new int[0];
static{
x[0] = 10;
}
public static void main(String[] args){
AX ax = new AX();
}
}

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Sat Mar 25, 2017 5:57 am
by admin
What happened when you tried to compile and execute it?

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Fri May 08, 2020 4:53 pm
by swarna pakeer
as per book OCAJP by Hanuman deshmukh,page no-285, it says we cannot throw checked exceptions from static initializer but instance initializers are allowed to throw checked exceptions in this case we should declare an exception thrown from an instance initializer in the throws clause of each constructor of the class. please clarify

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Fri May 08, 2020 4:59 pm
by admin
Not sure what you mean by clarify. The statement is quite clear itself. What happened when you tried it out?

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu May 14, 2020 2:57 pm
by swarna pakeer
what i mean is the explanation in the question says "If you try to throw a checked exception from a static or instance initializer block to the outside, the code will not compile." but the book says we can throw checked exceptions from the instance initializer if we declare it in all the constructors throws clause .since there is contraction between two statements i asked for an explanation .

Re: About Question enthuware.ocajp.i.v7.2.1326 :

Posted: Thu May 14, 2020 11:56 pm
by admin
The book is correct as shown by the following short code:

Code: Select all

public class TestClass{

  {
    if(true) throw new Exception(); //compiles
  }

  static {
    if(true) throw new Exception(); //does not compile
  }

  TestClass() throws Exception{ }
}
The explanation should be enhanced with this detail.
thank you for your feedback!