2015-01-02 18 views
13

Hiện tại tôi đang làm việc trên tối ưu hóa mã nơi tôi đang sử dụng thử .. cuối cùng khối để deference đối tượng của tôi.Làm thế nào cố gắng ... cuối cùng làm việc nội bộ

Nhưng tôi đã nhầm lẫn rằng cách trả về một đối tượng được quản lý khi tôi tạo tham chiếu null cho một đối tượng trong khối cuối cùng của mình. ??

Trong khi trả về một đối tượng trong khối thử, nó sẽ tạo ra một câu lệnh được biên dịch trước khi biên dịch? hoặc tạo tham chiếu mới trong heap trong khi nói đến câu lệnh return? hoặc chỉ trả về một tham chiếu hiện tại của một đối tượng?

Dưới đây là mã nghiên cứu của tôi.

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 là:

Bên trong khối try
đang Hash của str: -832.992.604
ở cuối cùng trước khi bolck
trong khối finally sau
nhắn: Hello world
đang Hash của tin nhắn: -832992604

Tôi rất ngạc nhiên khi thấy cả đối tượng quay lại và đối tượng gọi có cùng mã băm. Vì vậy, tôi nhầm lẫn về tham chiếu đối tượng.

Hãy giúp tôi xóa nội dung cơ bản này.

+2

mã băm được tạo dựa trên nội dung chứ không phải địa chỉ tham chiếu hoặc thứ gì đó. Vậy sự nhầm lẫn là gì? – SMA

+0

Cảm ơn bạn đã trả lời nhanh chóng. sự nhầm lẫn của tôi là tôi đang làm cho đối tượng của tôi null trong khối cuối cùng của tôi. Vì vậy, nơi đối tượng trở lại là cư trú và làm thế nào ?? – Pratik

+1

[JLS-14.20.2. Thực thi 'try-finally' và' try-catch-finally'] (https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2) có thể giúp xóa bỏ sự nhầm lẫn của bạn về 'cuối cùng'. Điều quan trọng cần lưu ý là Java 'String' là không thay đổi. Vì vậy, bạn đã trả lại một bản sao của giá trị đó, bạn không thể sửa đổi thể hiện được trả về cuối cùng. Nếu bạn trả về một 'StringBuilder' và được gọi là' setLength (0) 'ở cuối cùng thì bạn sẽ nhận được một độ dài bằng không' StringBuilder' trong người gọi của bạn. –

Trả lời

12

Phương pháp này không chính xác trả về một đối tượng. Nó trả về một tham chiếu đến một đối tượng. Đối tượng mà tham chiếu đề cập đến việc giữ nguyên bên trong và bên ngoài cuộc gọi phương thức. Bởi vì nó là cùng một đối tượng, mã băm sẽ giống nhau.

Giá trị của str tại thời điểm return str là tham chiếu đến chuỗi "Hello World". Câu lệnh return đọc giá trị của str và lưu nó làm giá trị trả về của phương thức.

Sau đó, khối cuối cùng được chạy, có cơ hội thay đổi giá trị trả về bằng cách chứa câu lệnh trả về của riêng nó.Thay đổi giá trị của str trong khối cuối cùng không thay đổi giá trị trả về đã đặt, chỉ có một câu lệnh trả về khác.

Vì thiết lập str đến null không có hiệu lực, bạn có thể xóa các câu lệnh như thế này. Nó sẽ đi ra khỏi phạm vi ngay sau khi phương pháp trả về anyway vì vậy nó không giúp với thu gom rác thải.

+0

Nó thực sự giúp đỡ đầy đủ cho tôi. Cảm ơn rất nhiều. Tôi có một nghi ngờ làm cho đối tượng như là một null sẽ không giúp thu gom rác thải ??. Không có tham chiếu nhiều hơn trong không gian heap cho loại đối tượng có trong phương pháp ?? – Pratik

+2

@prattpratt Khi phương thức trả về, thì các biến bên trong không còn tồn tại, do đó các giá trị chúng không còn quan trọng nữa. Chúng sẽ không được tính là các tham chiếu đến các đối tượng, do đó các đối tượng mà chúng tham chiếu có thể được thu thập, miễn là không có tham chiếu nào khác tồn tại. – fgb

+0

@prattpratt - Sẽ có một khe địa chỉ trả về (trên cùng của ngăn xếp) mà trên đó tham chiếu được trả lại phải được đẩy. Vì vậy, khi sự trở lại của cố gắng gặp phải, tham chiếu của "Hello World" được đẩy ở đó. Vì vậy, bất cứ điều gì xảy ra tiếp theo (gán lại tham chiếu đến 'null'), sẽ không thay đổi giá trị * trả về *. Nếu bạn gọi 'return str' trong * finally *, thì giá trị của' str' sẽ xuất hiện từ stack và null sẽ được cập nhật tại vị trí của nó. Vì vậy, 'null' sẽ được trả về. – TheLostMind

0

Hashcode() không phải để hiển thị tham chiếu. Thay vào đó, hashcode đang được sử dụng để kiểm tra xem 2 chuỗi có bằng nhau hay không. Vui lòng tham khảo http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()

Trả về mã băm cho chuỗi này. Mã băm cho đối tượng String được tính là s [0] * 31^(n-1) + s [1] * 31^(n-2) + ... + s [n-1]

Vì cả hai Chuỗi có cùng giá trị, tất nhiên mã băm giống nhau.

+0

Thậm chí sau đó, người hỏi đã mong đợi 'str' là null, do đó cần phải có một' NullPointerException'. –

+0

Không - Java chuyển giá trị và không tham chiếu. Giá trị được trả về và giá trị thay đổi cuối cùng có các tham chiếu khác nhau. – Rudy

+0

Có, đó là câu trả lời. Đó là điều mà OP không hiểu. Không phải cách tính hashcodes. –

1

Căn cứ vào 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 trợ giúp này :)

+0

@Downvoter có bất kỳ vấn đề nào với câu trả lời của tôi không? :) – hqt

+1

Không phải là downVoter, nhưng điều này không trả lời câu hỏi OPs. – TheLostMind

+1

@ TheLostMind Base dựa trên mã anh đã thử và bình luận của anh dưới bài viết của anh. 'Cảm ơn bạn đã trả lời nhanh chóng. sự nhầm lẫn của tôi là tôi đang làm cho đối tượng của tôi null trong khối cuối cùng của tôi. Vì vậy, nơi đối tượng trở lại là cư trú và làm thế nào? 'Tôi không nghĩ rằng tôi đã hiểu lầm anh ta :) – hqt

Các vấn đề liên quan