13

Currently I am working on code optimization where I am using try.. finally block to deference my objects.

But I have confusion that how returning an object is managed when I am creating null reference to an object in my finally block. ??

While returning an object in a try block, Will it create a pre-compiled statement during compilation? or create new reference in heap while it comes to return statement? or just return a current reference of an object?

Below is my research code.

public class testingFinally{
    public static String getMessage(){
        String str = "";
        try{
            str = "Hello world";
            System.out.println("Inside Try Block");
            System.out.println("Hash code of str : "+str.hashCode());
            return str;
        }
        finally {
            System.out.println("in finally block before");
            str = null;
            System.out.println("in finally block after");
        }
    }

    public static void main(String a[]){
        String message = getMessage();
        System.out.println("Message : "+message);
        System.out.println("Hash code of message : "+message.hashCode());
    }
}

Output is:

Inside Try Block
Hash code of str : -832992604
in finally bolck before
in finally block after
Message : Hello world
Hash code of message : -832992604

I am very surprised when I see both returning object and calling object have same hashcode. So I am confused about object reference.

Please help me to clear this fundamental.

Parth Soni
  • 11,158
  • 4
  • 32
  • 54
Pratik
  • 944
  • 4
  • 20
  • 2
    hashcode is created based on content and not reference address or something. So what's the confusion? – SMA Jan 02 '15 at 07:03
  • Thanks for your prompt reply. my confusion is i am making my object null in my finally block. so where return object is reside and how?? – Pratik Jan 02 '15 at 07:06
  • 1
    [JLS-14.20.2. Execution of `try-finally` and `try-catch-finally`](https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2) might help to clear your confusion about `finally`. It's important to note that Java `String` is immutable. So you've already returned a copy of that value, you can't modify the returned instance in finally. If you returned a `StringBuilder` and called `setLength(0)` in the finally then you'd get a zero length `StringBuilder` in your caller. – Elliott Frisch Jan 02 '15 at 07:06
  • Thanks elliott frisch, i have checked the flow of try...catch and try-catch-finally. finally will always gets executed. but as i had checked that return take placed after execution of finally and i have made my returning object null in my finally block. so in this case how and where that returning object will reside in memory?? – Pratik Jan 02 '15 at 07:11
  • 2
    @prattpratt - What to be *returned* is already decided in the try block. So, unless you do `return str`, in the `finally` block (in which case the current value to be returned will be popped from the top of the stack and replaced with the updated value i.e, null), the value returned will be `"Hello World"`. – TheLostMind Jan 02 '15 at 07:15
  • 1
    @TheLostMind - Thanks for your help. it will help me to understand detail fundamentals. – Pratik Jan 02 '15 at 07:32

3 Answers3

12

The method doesn't exactly return an object. It returns a reference to an object. The object that the reference refers to stays the same inside and outside the method call. Because it's the same object, the hashcode will be the same.

The value of str at the time of return str is a reference to the String "Hello World". The return statement reads the value of str and saves it as the return value of the method.

Then the finally block is run, which has the chance to change the return value by containing its own return statement. Changing the value of str within the finally block doesn't change the already set return value, only another return statement will.

Because setting str to null has no effect, you can remove statements like this. It will go out of scope as soon as the method returns anyway so it doesn't help with garbage collection.

fgb
  • 18,439
  • 2
  • 38
  • 52
  • Its really help full for me. Thanks a lot. I have a doubt making object as a null will not help to garbage collection??. There is no more reference in the heap space for this kind of objects which are in the method?? – Pratik Jan 02 '15 at 07:58
  • 2
    @prattpratt When the method returns, then the variables inside no longer exist, so the values they have no longer matter. They won't count as references to objects, so objects they refer to can be collected, as long as no other references exist. – fgb Jan 02 '15 at 08:12
  • @prattpratt - There will be a return address slot (top of stack) on which the reference to be returned has to be pushed. So, when the return of try is encountered, the reference of "Hello World" is pushed there. So, whatever happens next (reassigning the reference to `null`), will not change the *returned* value. If you call `return str` in *finally*, then the value of `str` will be popped from the stack and null will be updated in its place. So `null` will be returned. – TheLostMind Jan 02 '15 at 08:19
  • Thanks a lot i got my answer now its clear for me. Thanks a lot again. – Pratik Jan 02 '15 at 08:30
  • Your explanation of hashCode() is misleading. [HashCode](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode()) is based on the value of the String, not the object reference. Two separate Strings with the same value will return the same hashCode. – eclipz905 Jan 02 '15 at 14:56
1

Base on JLS 14.20.2 Execution of try-catch-finally

If execution of the try block completes normally, then the finally block is executed, and then there is a choice:    
    If the finally block completes normally, then the try statement completes normally.
    If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.

Hope this help :)

hqt
  • 29,632
  • 51
  • 171
  • 250
  • @Downvoter are there any problems with my answer? :) – hqt Jan 02 '15 at 07:10
  • 1
    Not the downVoter, but this doesn't answer the OPs question. – TheLostMind Jan 02 '15 at 07:11
  • 1
    @TheLostMind Base on code he tried and his comment under his post. `Thanks for your prompt reply. my confusion is i am making my object null in my finally block. so where return object is reside and how??` I don't think I have misunderstand him :) – hqt Jan 02 '15 at 07:12
  • 2
    In this case, the `finally` and `try` completed *normally*. The OP is asking *why did I not get null*? – TheLostMind Jan 02 '15 at 07:19
0

Hashcode() is not for showing a reference. Instead, hashcode is being used to check if 2 string are equal to each other. Please refer to http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()

Returns a hash code for this string. The hash code for a String object is computed as s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

Since both String are having the same value, of course the hashcode are the same.

Rudy
  • 7,008
  • 12
  • 50
  • 85