2012-04-03 22 views
16

Có một tính năng của ngôn ngữ Apple Objective-C thực sự hữu ích đối với tôi: Tôi có thể truyền các khối mã làm đối số trong các phương thức.Khối ObjectiveC Java tương đương

Tôi cũng muốn làm điều đó trong Java. Cái gì như:

myManager.doSomethingInTransaction(function() { 
    dao.save(); 
}); 

Vì vậy, các đối tượng myManager sẽ thực thi mã của tôi giữa một startTransaction() và một endTransaction() phương pháp.

Có cách nào để làm điều đó trong Java không?

+0

Câu trả lời đơn giản là "không", không có chức năng như vậy trong Java. –

+0

Cho năm 2014, câu trả lời có vẻ là "chỉ cần sử dụng Runnable". – Fattie

Trả lời

40

Thật không may, Java không hỗ trợ điều này. Nhưng bạn có thể nhận được chức năng tương tự với các lớp ẩn danh.

Để làm như vậy, trước tiên bạn xác định một giao diện:

interface TransactionAction { 
    public void perform(); 
} 

doSomethingInTransaction sau đó cần được xác định để có một TransactionAction như một cuộc tranh cãi.

Sau đó, khi bạn gọi nó, làm như sau:

myManager.doSomethingInTransaction(new TransactionAction() { 
    public void perform() { 
     dao.save(); 
    } 
}); 
+1

Ví dụ này sẽ không hoạt động vì 'do' là từ khóa. – Landei

+0

Vâng, chỉ cần nhận thấy điều đó. – Taymon

+0

Cảm ơn bạn. Nó không thể rõ ràng hơn thế này! :) –

11

Không này không tồn tại trong Java (chưa). Giải pháp thay thế là sử dụng giao diện Runnable:

myManager.doSomethingInTransaction(new Runnable() { 
    public void run() { 
     dao.save(); 
    } 
}); 

hoặc bất kỳ giao diện nào có phương pháp đơn lẻ sẽ thực hiện.

+0

Đây là giải pháp tốt nhất! –

3

bạn có thể sử dụng một giao diện giống như

interface CodeBlock { 
    void execute(); 
} 

chức năng sẽ trông như thế

someType functionToBeExecuted(CodeBlock cb) { 
    ... 
} 

nó sẽ được gọi như

functionToBeExecuted(new CodeBlock() { 
    void execute() { 
     // blah 
    } 
}); 

Nhưng nếu mã của bạn sẽ có thể truy cập các biến hoặc các trường trong sẽ chuyên biệt hơn. Ngoài ra hiệu suất sẽ thấp hơn theo cách này vì các đối tượng mới.

2

này bây giờ có thể trong Java 8 sử dụng một biểu thức lambda:

myManager.doSomethingInTransaction(() -> { 
    dao.save(); 
}); 

Hoặc ngắn gọn hơn:

myManager.doSomethingInTransaction(() -> dao.save()); 

triển khai của bạn của doSomethingInTransaction nên chấp nhận một tham số Runnable, hoặc bất kỳ đơn phương pháp khác giao diện với chữ ký phương thức phù hợp.

Bạn có thể tìm thấy tài liệu của Oracle ở đây: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

+2

Điều này thậm chí có thể được đơn giản hóa thành 'myManager.doSomethingInTransaction (dao :: save);' – Palle