Q:

Return primitive data type from a catch block in java

i'm playing around with exceptions for learning purposes and i have a question. Please see the code below:
public static void main(String[] args) {

    System.out.print(getNumber());

}

public static double getNumber() {

    double number =10;

    try {
        String [] students = {"nick","george"};
        System.out.println(students[5]);
    }
    catch (ArrayIndexOutOfBoundsException ex ) {
        System.out.println("In catch block "+ number);
        return number;
    }
    finally {
        number +=10;
        System.out.println("The value is now "+ number);
    }
    System.out.println("hiiiii");
    return number;
}

Why in this case the output from the main method will be 10 and why if i run the same example and return an object the value will be changed?
public static void main(String[] args) {
    System.out.println("In main  is "+getStringBuffer());
}

public static StringBuffer getStringBuffer() {

    StringBuffer number = new StringBuffer("10");

    try {
        String [] names= {"george" ,"nick"};
        System.out.println(names[5]);
    }

    catch (ArrayIndexOutOfBoundsException ex1) {
        System.out.println("In catch block "+ number);
        return number;
    }

    finally {
    number.reverse();   
        System.out.println("In finally is "+ number);
    }
    System.out.println("hiiii");
    return number;
}

A:

Because in the first example, you are returning a primitive and its return value is already on the stack and cannot be changed by the finally block.
In the second example, you are returning a reference variable and the value it points to can be changed by the finally block.

A:

The value returned by the method is set as of the return statement it encounters. So
return number;

does not mean "remember that you're going to return the number variable", it means "evaluate the number variable, and remember the resulting value to use it as the return value". Changing the contents of the number variable later (in the finally block) has no effect on the value being returned by the method, that's already been determined.
How do we know this? Because return has to evaluate the expression (per §14.17 of the JLS). Suppose, for instance, you had
return number + 5;

...you wouldn't expect to get 25 because you had 10, hit the return statement, then added another 10 in the finally block, and then the expression added 5 more, right? return evaluates the expression and remembers that value as the method's return value.
In the object example you give, the value being returned isn't being changed in the finally block. It's still just a reference to the object. You're changing the state of the object whose reference is being returned, but the reference is not being changed. If you replaced
number.reverse();

with
number = new StringBuffer();

...you'd see that you get exactly the same behavior as with a double, because in that case, you're changing the value held in number (the reference to the object), just like you do with number += 10;.

