2017-03-24 23 views
6

Có một phương pháp get(sql) (Tôi không thể sửa đổi nó). Phương thức này trả về MyObjects và nó phải ở trong try catch block vì JqlParseException có thể ở đó. Mã của tôi là:Ném ngoại lệ tùy chọn trong Java8

String sql = something; 
try{ 
    MyObject object = get(sql); 
} catch(JqlParseException e){ 
    e.printStackTrace(); 
} catch(RuntimeException e){ 
    e.printStackTrace(); 
} 

Tôi muốn loại bỏ cố gắng nắm bắt và sử dụng Optional lớp, tôi đã cố gắng:

MyObject object = Optional.ofNullable(get(sql)).orElseThrow(RuntimeException::new); 

nhưng lực lượng IDE có cố gắng nắm bắt quá. Và cho:

MyObject object = Optional.ofNullable(get(sql)).orElseThrow(JqlParseException::new)); 

là lỗi (trong IDE) The type JqlParseException does not define JqlParseException() that is applicable. Có cách nào để tránh thử bắt khối và sử dụng tùy chọn không?

+1

Chuyển đến định nghĩa 'get', xem nếu nó nói' ném JqlException'. Nếu có, bạn phải sử dụng try ... catch. – Sweeper

+2

Có vẻ như khá nhiều người đang cân nhắc Tùy chọn là cấu trúc luồng điều khiển NextGeneration ™. Đó sẽ không xảy ra. Tùy chọn, cũng như các đối tác nguyên thủy của nó, vốn dĩ không thể xử lý loại tác vụ này. Nó không được thiết kế để thay thế hoàn toàn các cấu trúc dòng điều khiển như if-else hoặc try-catch. Thay vào đó, nó tập trung vào việc loại bỏ các kiểm tra vô giá trị vô tận này. – glee8e

+0

@ glee8e * ['Tùy chọn'] tập trung vào việc loại bỏ các kiểm tra vô giá vô hạn đó. * Tôi sẽ cụ thể hơn. Nhiều người sẽ nhảy đến kết luận rằng họ nên thay thế tất cả các lần xuất hiện của 'null' bằng' Tùy chọn', điều này trái với ý định của các nhà thiết kế 'Optional'. – Jubobs

Trả lời

7

Optional không thực sự nhằm mục đích xử lý ngoại lệ, nó được thiết kế để xử lý các giá trị tiềm năng mà không làm gián đoạn luồng chương trình của bạn. Ví dụ:

myOptional.map(Integer::parseInt).orElseThrow(() -> new RuntimeException("No data!"); 

này sẽ tự động bỏ qua bước map nếu tùy chọn hoàn toàn trống rỗng và đi ngay vào throw bước - một dòng chảy không gián đoạn chương trình tốt đẹp.

Khi bạn viết:

myOptionalValue.orElseThrow(() -> new RuntimeException("Unavailable")); 

... những gì bạn đang thực sự nói là: Return giá trị tùy chọn của tôi, nhưng ném một ngoại lệ nếu nó không phải là có sẵn.

Điều bạn muốn là cách tạo tùy chọn (ngay lập tức bắt ngoại lệ) và sẽ tính lại ngoại lệ đó khi bạn thử sử dụng tùy chọn.

4

Đó không phải là cách Tùy chọn hoạt động. Chúng không làm cho các khối try-catch bị lỗi thời. Tuy nhiên, bạn có thể giới thiệu một hàm bao bọc mới như sau:

public Optional<MyObject> getMyObject(final String jql) { 
    try { 
     return Optional.ofNullable(get(sql)); 
    } catch (final JqlParseException e) { 
     return Optional.empty(); 
    } 
} 

Bạn sẽ không phải đối phó với ngoại lệ nữa, nhưng bạn sẽ không biết nếu có lỗi nếu bạn có tùy chọn trống tốt.