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

Moderator: admin

Javanaut

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

Post by Javanaut » Sun Aug 12, 2012 11:58 am

I am still not clear why a) a nullpointerexception is not thrown or b) why the post-increment has no effect on the value of index.

This is a real brainer. :?

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Sun Aug 12, 2012 8:04 pm

1. first index = 2 will be executed, which assigns 2 to index. After that null[2] is executed, which throws a NullPointerException. But this exception is caught by the catch block, which prints nothing. So it seems like NullPointerException is not thrown but it actually is.

2. post increment is not applied to index. It is applied to the result of getArray()[2]. Of course, before ++ can be executed, a NullPointerException is thrown as explained above.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

Javanaut

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

Post by Javanaut » Mon Aug 13, 2012 1:02 pm

Ah, Thank-you Paul for the explanation. 8-)

Although, I see now that this code does throw a NullPointerException especially upon calling the printStackTrace method on the exception object, but if I pass a an array instead of null the index variable is still not post-incremented. :shock:

Code: Select all

public class Test {

	public static int[] getArray() { return new int[8]; }
	
	
	public static void main(String[] args) {
		
		
		int index = 1;
		try { 
			getArray()[index=2]++;
		}
		catch (Exception e) { e.printStackTrace();} // empty catch
		System.out.println("index = " + index);

	}

}

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Mon Aug 13, 2012 8:23 pm

Javanaut wrote:Ah, Thank-you Paul for the explanation. 8-)

Although, I see now that this code does throw a NullPointerException especially upon calling the printStackTrace method on the exception object, but if I pass a an array instead of null the index variable is still not post-incremented. :shock:

Code: Select all

public class Test {

	public static int[] getArray() { return new int[8]; }
	
	
	public static void main(String[] args) {
		
		
		int index = 1;
		try { 
			getArray()[index=2]++;
		}
		catch (Exception e) { e.printStackTrace();} // empty catch
		System.out.println("index = " + index);

	}

}
As I said before, ++ is not applied on index. We are not doing index++, we are going getArray()[2]++, so whatever is the result of getArray[2], that is incremented. Not index.
If you like our products and services, please help us by posting your review here.

Javanaut

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

Post by Javanaut » Tue Aug 14, 2012 12:12 pm

heavy :o

DooBeeDoo

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

Post by DooBeeDoo » Tue Aug 21, 2012 8:03 am

Hi Enthuware Admin,

Would you kindly enlighten me on the following:

Snippet 1:

Code: Select all

public class ArrayKoPo {

    public static int[] getArray() {
        return null;
    }

    public static void main(String args[]) {
        int i = 0;
        try {
            int j = getArray()[i++];
        } catch (Exception e) {
            System.out.println(i); //prints 1 <---- This one I understand.
        }
    }
}
Snippet 2:

Code: Select all

public class ArrayKoPo {

    public static int[][] getArray() {
        return null;
    }

    public static void main(String args[]) {
        int i = 0;
        try {
            int j = getArray()[i++][i++];
        } catch (Exception e) {
            System.out.println(i); //prints 1 <---- This one I don't understand. I thought 2 will be printed.
        }
    }
}
I read somewhere in the explanation that if the array reference produces null, then a NPE is thrown at runtime, but only after all parts of the array reference expression have been evaluated and only if these evaluations completed normally.

But how come the variable i is not incremented twice in the second block of code?

What am I missing?

Thanks.

kappert
Posts: 2
Joined: Fri Dec 28, 2012 10:42 am
Contact:

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

Post by kappert » Sun Dec 30, 2012 12:49 pm

This was very surprising for me, too. To analyze complicated expressions, it may be an idea to try to duplicate what the compiler does, namely to build an expression tree.

This should also provide the answer to DooBeeDoo's question, "why is i incremented only once when getArray() returns null?" in this expression:

Code: Select all

int j = getArray()[i++][i++];
From my notes on how to create and use an expression tree (see also http://introcs.cs.princeton.edu/java/11precedence/):
1) Break into subexpressions recursively. The breaks happen at the operators of lowest precedence.
2) Within the same precedence, associativity determines sequence.
3) Traverse expression tree, left to right, leaves before nodes.

Let's start with a simple example, accessing a one-dimensional int[] myArray.
Expression: myArray[1]
Expression tree (nodes are operators, the slashes and backslashes are an attempt at painting the branches):

Code: Select all

          []
         /  \
  myArray     1
Traversal of the expression tree:
1) myArray (leaf)
2) 1 (leaf)
3) apply access array operator [] on the two leaves

Accessing a two-dimensional array:
Expression: myArray[1][2]
Expression tree:

Code: Select all

              []
             /  \
          []      2
         /  \
  myArray     1
Traversal:
1) myArray (leaf)
2) 1 (leaf)
3) apply access array operator [] on "myArray" and index 1, the result is a new leaf "IntArray1"
4) 2 (leaf)
5) apply access array operator [] on "IntArray1" and index 2

And now the more complicated expression (I did not split up all unary operators into "operator" and "operand" but for simplicity simply wrote "i++"):
Expression: int j = getArray()[i++][i++]
Expression Tree:

Code: Select all

                        =
                      /   \
                    j      []  
                         /    \
                       []       i++
                     /    \
             getArray()    i++
Traversal:
1) j (leaf)
2) getArray() (leaf), resulting in "TheArray2D"
3) i++ (leaf), resulting in "FirstIndex"
4) apply access array operator on "TheArray2D" with "FirstIndex", resulting in "IntArray1"
5) i++ (leaf), resulting in "SecondIndex"
6) apply access array operator on "IntArray1" (result of 4) using "SecondIndex", resulting in "TheIntegerResult"
7) apply assignment operator on "j" and "TheIntegerResult"

This should clear up why the second increment of i (step 5) never happens: A NullPointerException occurs at step 4 of the tree traversal. The first increment in step 3 is still done, but step 5 never happens.

You may want to play around with building expression trees for very simple expressions like 1 + 2 * 3 and so on to get a feel for it.
Please post a reply if you have a clearer explanation of how to build the expression tree.

philfrei

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

Post by philfrei » Wed Jan 23, 2013 8:47 pm

I found the explanation confusing. In the top half, the statement is made that "first, index = 2 will be evaluated" but in the second half "the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated". These two statements, on the surface, contradict.

Why do you say "appears to be"? That kind of muddies things too, doesn't it?

If I now understand correctly, the order of occurrences is as follows:
1) expression to left of brackets is evaluated; (null is returned in place of int[])
2) expression within brackets is evaluated;
3) attempt to obtain the value in the array is performed; (throwing null exception)
and
4) the ++ (stuff after the []) would be performed on the array value IF it had been successful.

As a reply to the 2D array question from DooBeeDoo, a simpler answer would be that a 2D array is actually implemented as array of arrays, and the null exception occurs during the first array lookup. In other words, the second [] is only evaluated after the first left-side expression and [] return a sub array. That is my guess as to what is going on there.

By the way thanks for creating this excellent learning product! I am getting a lot out of it.

Sweetpin2
Posts: 27
Joined: Thu Feb 07, 2013 9:46 pm
Contact:

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

Post by Sweetpin2 » Thu Feb 28, 2013 1:14 pm

Javanaut wrote:Ah, Thank-you Paul for the explanation. 8-)

Although, I see now that this code does throw a NullPointerException especially upon calling the printStackTrace method on the exception object, but if I pass a an array instead of null the index variable is still not post-incremented. :shock:

Code: Select all

public class Test {

	public static int[] getArray() { return new int[8]; }
	
	
	public static void main(String[] args) {
		
		
		int index = 1;
		try { 
			getArray()[index=2]++;
		}
		catch (Exception e) { e.printStackTrace();} // empty catch
		System.out.println("index = " + index);

	}

}

When i change the code as below

int t = getArray()[index=2]++;
System.out.println(t);

Why i am getting value of t as 0 instead of 1 as int array is initialized with 0 & doing a post incerement should make it 1?

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Thu Feb 28, 2013 5:42 pm

because it is post increment i.e. you assign the value first and then increment.
If you like our products and services, please help us by posting your review here.

Rafael
Posts: 3
Joined: Thu Jul 11, 2013 5:39 am
Contact:

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

Post by Rafael » Fri Aug 30, 2013 6:45 am

Sorry but I don't understand this expression

Code: Select all

   getArray()[index=2]++
What means? How does it work? I'm looking for information on google but I don't understand this format call : method()[];


Regards.

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Fri Aug 30, 2013 5:44 pm

Think of it this way:

someArray = getArray()
someInt = someArray[index=2]
someInt++

So, first getArray() returns an array, on which you apply [index] to access a specific element, and then you increment the value that you get by applying index to the array.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

Rafael
Posts: 3
Joined: Thu Jul 11, 2013 5:39 am
Contact:

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

Post by Rafael » Mon Sep 02, 2013 5:34 pm

Thanks Paul, I had never seen that expression and I was a little confused.

bbakla
Posts: 3
Joined: Wed Mar 18, 2015 1:16 am
Contact:

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

Post by bbakla » Wed Mar 18, 2015 1:23 am

Hi,
I modified the code as below:

Code: Select all

public static int[] getArray()
	{
		return new int[]{0, 1, 4, 6, 8, 10};
	}

public static void main(String[] args)
	{
		int index = 1;
		int g = 0;
		
		try
		{
			 g = getArray()[index=2]++;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		System.out.println("index = " + index);
		System.out.println("index = " + g);
		
	}}

Since it is a post increment and it seems to increment index not result. The print out is

Code: Select all

index = 2
index = 4
But when I change the code in try expression as below

Code: Select all

g = getArray()[index=2]<<2;
g is printed out 16 so it shifts actually the result!..

Can you please help me to understand that?

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Wed Mar 18, 2015 2:42 am

Your print statement has a problem. It says "index =" but prints g.
index is not incremented due to ++. It is set to 2 because of the assignment operation index=2
If you like our products and services, please help us by posting your review here.

bbakla
Posts: 3
Joined: Wed Mar 18, 2015 1:16 am
Contact:

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

Post by bbakla » Sat Mar 28, 2015 11:53 am

My intention is actually to print g.

if the ++ doesnt increment the variable index, shouldn't g be 5? I guess ++ operator increments g in this case

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Sat Mar 28, 2015 9:31 pm

bbakla wrote:My intention is actually to print g.

if the ++ doesnt increment the variable index, shouldn't g be 5?
No, because it is postfix.
I guess ++ operator increments g in this case
No, it doesn't. Not sure why you think so.
If you like our products and services, please help us by posting your review here.

bbakla
Posts: 3
Joined: Wed Mar 18, 2015 1:16 am
Contact:

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

Post by bbakla » Sun Mar 29, 2015 1:58 pm

Now I got it. postfix increments the element in the array..

ElizabethCM
Posts: 29
Joined: Sun Apr 05, 2015 11:26 am
Contact:

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

Post by ElizabethCM » Sat May 16, 2015 2:40 am

Hello,

Could you please explain me the observation written at this exercise with a small example?

"In an array access, the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated.
Note that if evaluation of the expression to the left of the brackets completes abruptly, no part of the expression within the brackets will appear to have been evaluated."

If we have this:
 int[] a = { 1, 2, 3, 4 };       
int[] b = { 2, 3, 1, 0 };       
System.out.println( a [ (a = b)[3] ] );

First it evaluates the whole expression: a[expression]. Keeps this on its stack trace.
Then evaluates (a=b)[3]. Here a points to the same array as b. So a[3] is equivalent to b[3] which is 0.
When it gets back on the stack to evaluate a[expression], which one is evaluated here? the initially declared array a or the one that is pointing to the same array as b?

Thank you for explaining ;)

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Sat May 16, 2015 4:02 am

1. As it clearly says, "the expression to the left of the brackets appears to be fully evaluated ",
in a [ (a = b)[3] ], the expression to the left of the brackets is "a", which is evaluated first. Which means, the reference to the object pointed to be a is put on the stack first.

2. Now, (a = b)[3] is evaluated. Again, the expression to the left of brackets is (a = b), thus b is assigned to a. (This doesn't change the value that has already been put on the stack in previous step.)

3. Now, a[3] is evaluated, which is actually same as b[3] because a points to the same array as b i.e. 0.

4. Finally, [0] is applied to the original reference that was stored on the stack in step 1. It points to the array { 1, 2, 3, 4 }. Thus, the complete expression finally returns 1.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

qmwuzapz
Posts: 3
Joined: Sun Jan 29, 2017 1:54 pm
Contact:

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

Post by qmwuzapz » Thu Feb 02, 2017 10:07 am

from the exam explanation:
In an array access, the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated. Note that if evaluation of the expression to the left of the brackets completes abruptly, no part of the expression within the brackets will appear to have been evaluated.
Is this the case ?

Code: Select all

class X {
    public static int [] apply(){
       if (Y.i==Y.i)throw new NullPointerException();
        return new int[]{10,8,4,6};
    }
}
public class Y {
    public static int i = 0;
    public static void main(String[] args) {
        try {
            System.out.println(X.apply()[i = 3]);
        } finally {
            System.out.println(i);
        }
    }
}

EricLeesburg
Posts: 3
Joined: Sun Feb 26, 2017 12:35 pm
Contact:

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

Post by EricLeesburg » Sun Feb 26, 2017 1:05 pm

Code: Select all


     class Test  {

         public static int[ ] getArray() {  return null;  } 

         public static void main(String[] args)    {      
         
               int index = 1;     

               try{         
 
                     getArray()[index=2]++;     //1 
                   
                     } catch (Exception e){  }  //empty catch      
  
             System.out.println("index = " + index);   
             }
      }
For the statement 1, my understanding is that it equals the statements below:

Code: Select all

                 
                int temp= getArray()[index=2];
                
                 temp++;
and getArray()[index=2] actually is a element of the array. So by the explanation " In an array access, the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated. Note that if evaluation of the expression to the left of the brackets completes abruptly, no part of the expression within the brackets will appear to have been evaluated.", the getArray () should be evaluated first, then the index=2 statement. In this case, getArray() throws a NullPointerException which leaves the index=2 statement unevaluated. So, what's wrong here?
Last edited by admin on Sun Feb 26, 2017 10:19 pm, edited 1 time in total.
Reason: Please enter code inside [code] [/code] tags

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Sun Feb 26, 2017 10:18 pm

qmwuzapz wrote:from the exam explanation:
In an array access, the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated. Note that if evaluation of the expression to the left of the brackets completes abruptly, no part of the expression within the brackets will appear to have been evaluated.
Is this the case ?

Code: Select all

class X {
    public static int [] apply(){
       if (Y.i==Y.i)throw new NullPointerException();
        return new int[]{10,8,4,6};
    }
}
public class Y {
    public static int i = 0;
    public static void main(String[] args) {
        try {
            System.out.println(X.apply()[i = 3]);
        } finally {
            System.out.println(i);
        }
    }
}
Yes, i will remain 0. i = 3 will not be executed.
If you like our products and services, please help us by posting your review here.

admin
Site Admin
Posts: 8619
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin » Sun Feb 26, 2017 10:24 pm

Your getArray method doesn't throw a NullPointerException. It returns null. So the statement, "if evaluation of the expression to the left of the brackets completes abruptly," doesn't apply here.
If you like our products and services, please help us by posting your review here.

MariaRoxana
Posts: 2
Joined: Sun Dec 09, 2018 10:33 am
Contact:

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

Post by MariaRoxana » Sat Mar 23, 2019 1:36 am

Hello,

Can someone please give an example when it applies this rule "if evaluation of the expression to the left of the brackets completes abruptly"? Meaning in which cases the evaluation completes abruptly?

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests