2016-01-11 27 views
6

Tại sao kết quả của mã sau là 3, tại sao cuối cùng có được chấm dứt và nhận ra phương pháp thậm chí tho kiểm tra trình biên dịch thử đầu tiên và tại sao sự trở lại trong thử không chấm dứt phương pháp?cố gắng/cuối cùng mà không bắt với tuyên bố trở lại?

public int returnVal(){ 
    try{ 
     return 2; 
    } 
    finally{ 
     return 3; 
    } 
} 
+1

Khối 'cuối cùng' luôn được gọi là cuối cùng, đó là lý do tại sao nó được gọi là" cuối cùng "(nghĩ về" thử này, bắt bất kỳ ngoại lệ và cuối cùng làm điều đó "). – Thomas

+2

Khối 'cuối cùng' là * luôn luôn * thực hiện bất kể vấn đề gì .. –

+0

yeah tôi hiểu điều đó nhưng tại sao trình biên dịch bỏ qua câu lệnh trả về trong lần thử ngay cả khi nó được đưa vào nó tại thời gian chạy chấm dứt phương thức –

Trả lời

4

Xem JLS 14.17

Có thể thấy, sau đó, rằng một tuyên bố trở lại luôn hoàn thành đột ngột.

Các mô tả trước nói "cố gắng chuyển điều khiển" thay vì chỉ "kiểm soát chuyển" bởi vì nếu có bất kỳ câu lệnh thử nào (§14.20) trong phương thức hoặc hàm tạo có khối thử hoặc điều khoản bắt chứa câu lệnh trả về, thì các mệnh đề cuối cùng của các câu lệnh try đó sẽ được thực hiện, theo thứ tự, trong cùng đến ngoài cùng, trước khi điều khiển được chuyển tới người gọi của phương thức hoặc hàm tạo. Việc hoàn thành một mệnh đề cuối cùng đột ngột có thể làm gián đoạn việc chuyển giao quyền kiểm soát được bắt đầu bằng một câu lệnh trả về.

Kiểm tra các cụm từ attempts to transfer control và câu cuối cùng. Các cố gắng trả lại để chuyển các controll, aftwerwards cuối cùng disrupt the transfer of control initiated by a return statement.

Nói cách khác, hãy thử attempts to transfer the controll, nhưng vì việc thực hiện khối cuối cùng vẫn mở để thực thi và chứa câu lệnh trả về, việc chuyển điều khiển trong khối cuối cùng có số cao hơn preceding. Đó là lý do tại sao bạn thấy giá trị 3, được trả lại bên trong khối cuối cùng.

4

finally được thực hiện trước khi trả lại giá trị từ try (hoặc catch).

Nếu trong câu hỏi finally một tuyên bố return hiện diện, nó sẽ ghi đè trở lại khối try (hoặc catch).

Vì vậy, cũng trong trường hợp này sự trở lại của cuối cùng thắng:

try { 
    // Exception thrown 
    return 2; 
} catch (Exception e) { 
    return 1; 
} finally { 
    return -1; // Always returns -1 also if a return statement is present in the try and in the catch clause 
} 
+0

+1 vì dễ hiểu hơn nhiều so với câu trả lời hàng đầu (với mức giá ít thông tin hơn, dĩ nhiên). – domsson

0

Khối cuối cùng luôn được thực hiện trước khi điều khiển được trả về chức năng gọi. Vì vậy, trong trường hợp này trước khi trở về 2, nó sẽ gọi cuối cùng và sẽ trả lại 3.

1

Tại sao việc trả lại thử không chấm dứt phương pháp?

Is it bad practice to return from within a try catch finally block?

Bạn cần phải lưu ý rằng khi bạn đặt trở lại bên trong một câu lệnh try-catch, sự trở lại bản thân được tổ chức và khối xử lý exeption quản lý.

Khối ngoại lệ chỉ lưu trữ trở lại của bạn và nó thực sự trả về nó chỉ sau khi tất cả các xác minh được thực hiện, trong đó không có nghĩa là khối cuối cùng sẽ thực sự có ảnh hưởng đến lợi nhuận của bạn:

public int returnVal() { 
    int i = 0; 
    try { 
     return i; 
    } 
    finally { 
     i = 99; 
    } 
} 

Trong trường hợp này, lợi nhuận sẽ vẫn là 0.

Nhưng trong trường hợp bạn đã đề cập trong câu hỏi, bạn sẽ ảnh hưởng đến lần thứ hai và khối ngoại lệ không muốn cho phép bạn quay trở lại cho đến khi hoàn thành TẤT CẢ xác minh của nó, bạn chỉ luôn luôn lưu trữ một giá trị trả lại 2 lần trong khối ngoại lệ của bạn. Kết quả sẽ luôn là 3.

Chỉ cần ghi nhớ rằng nếu bạn đặt trả lại bên trong một thử-catch-cuối cùng, trở lại đó sẽ không trở lại cho đến khi khối cuối cùng đã chạy; sự trở lại chính nó chỉ được lưu trữ cho đến khi mọi thứ đã được xác minh.

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