2012-11-11 36 views

Trả lời

14

Nếu bạn có một đối tượng (như một ExecutorService) mà đòi hỏi bạn phải cung cấp một đối tượng Callable<T>, bạn có thể vượt qua nó một Callable<Void> để cho biết rằng Callable của bạn không trả lại bất cứ điều gì. Callable<T> phải được tham số hóa trên một số loại, do đó, Void được cung cấp để cho biết thiếu loại.

12

- Không giống như giấy gói khác Void lớp không cửa hàng một giá trị kiểu void của riêng mình và do đó là không phải là một wrapper trong bản chất thật.

- Lớp Void theo javadoc tồn tại vì thực tế rằng một số lần chúng tôi có thể cần phải đại diện cho từ khóa khoảng trống như một đối tượng.

- Nhưng tại cùng một điểm chúng tôi không có thể tạo ra một thể hiện của lớp Void sử dụng operator.This mới là bởi vì các nhà xây dựng trong Void đã khai báo là tin. Hơn nữa lớp Void là một lớp cuối cùng có nghĩa là không có cách nào chúng ta có thể kế thừa lớp này.

- Vì vậy, mục đích duy nhất còn lại cho sự tồn tại của lớp Voidphản ánh, nơi chúng tôi có thể nhận được các loại trở lại của một phương pháp như void.

+0

Không có sử dụng thực tế của 'Danh sách '. –

+0

Nhưng nếu bạn muốn sử dụng không thực tế, một 'Danh sách ' có thể được sử dụng như một không gian rất không hiệu quả :-) –

+0

Bạn là đúng mặc dù. 'Void' (không) -type trong Java không có nghĩa giống với' void' trong C/C++. Loại danh sách mà bạn không quan tâm về loại phần tử là 'Danh sách ' ... không phải 'Danh sách '. –

3

API phản chiếu java sử dụng Void.TYPE để thể hiện kiểu trả về của phương thức trả lại khoảng trống như Luke Woodward chỉ ra. (Trả lại Void.class như tôi đã nghĩ trước đây sẽ gây ra một sự mơ hồ với các phương thức trả về khai báo một kiểu trả về java.lang.Void).

void test(){...}; 

Method handleForTest = ...; 
assert(handleForTest.getReturnType() == Void.TYPE); 

bài java 1,5 Void có thể được sử dụng trong các lớp học tổng quát để chỉ ra rằng họ không trả về giá trị - việc thực hiện vẫn phải trả về null, nhưng nó có thể được bỏ qua vì đó là giá trị chỉ có giá trị cho các loại Void.

interface<T> Example{ 
     //Implementations may do something and return a result 
     T doSomeThing(); 
} 

class ExampleVoid implements Example<Void>{ 
     //does something without returning a result 
     Void doSomething(){return null;} 
} 

Cũng java cho phép đưa ra một kiểu trả cụ thể hơn khi ghi đè lên một phương pháp, điều này về cơ bản là giống như ví dụ chung chung ở trên, chỉ để chứng minh rằng nó hoạt động mà không cần Generics nếu kiểu trả ban đầu là Object.(Nó được giới hạn trong đối tượng kể từ Void theo quy tắc tương tự như tất cả các loại java khác, thật đáng buồn không có cách nào để sử dụng không tên vô loại này)

interface Example{ 
     //Implementations may do something and return a result 
     Object doSomeThing(); 
} 

class ExampleVoid implements Example{ 
     //does something without returning a result 
     Void doSomething(){return null;} 
} 
+0

API phản chiếu Java sử dụng 'void.class' làm kiểu trả về của các phương thức' void', không phải là 'Void.class'. Trong ví dụ đầu tiên của bạn, xác nhận sẽ thất bại. –

+0

@LukeXin chào cảm ơn, tôi đã cập nhật câu trả lời của mình – josefx

2

JLS#14.8. Expression Statements

Không giống như C và C++, ngôn ngữ lập trình Java chỉ cho phép một số dạng biểu thức nhất định được sử dụng làm câu lệnh biểu thức. Lưu ý rằng các ngôn ngữ lập trình Java không cho phép một "diễn viên để làm mất hiệu lực" - khoảng trống không phải là một loại - vì vậy C lừa truyền thống của văn bản một báo cáo biểu hiện như:

(void)... ; // incorrect! 

không công việc. Mặt khác, ngôn ngữ lập trình Java cho phép tất cả các kiểu biểu thức hữu ích nhất trong các câu lệnh biểu thức, và nó không yêu cầu lời gọi phương thức được sử dụng như một câu lệnh biểu thức để gọi ra một phương thức void, vì vậy một thủ thuật gần như không bao giờ cần thiết. Nếu cần một thủ thuật, hoặc một câu lệnh gán (§15.26) hoặc một câu lệnh khai báo biến cục bộ (§14.4) có thể được sử dụng thay thế.

JLS#15.8.2. Class Literals

Loại void.class (§8.4.5) là Class<Void>.

JLS#8.4.5. Method Return Type

Kết quả của một phương pháp kê khai hoặc kê khai các loại giá trị mà trở về phương pháp (kiểu trả về), hoặc sử dụng các khoảng trống từ khóa để chỉ ra rằng phương pháp này không trả về giá trị .

Java doc Void

Lớp Void là một lớp giữ chỗ uninstantiable để giữ một tham chiếu đến đối tượng Class đại diện cho từ khóa trống Java.

Nó được sử dụng cho mục đích phản ánh khi bạn đang muốn kiểm tra kiểu trả về của một phương pháp

if (getClass().getMethod("someMethod").getReturnType() == Void.TYPE) 

Cùng được áp dụng với các phương pháp chung.

final Callable<Void> callable = new Callable<Void>() { 
     public Void call() { 
      return null; 
     } 
    }; 
2

Lý do

Loại Void đã được giới thiệu để cho phép gọi lưng và giao diện với hệ thống bên ngoài (JNI, JavaScript cuộc gọi từ applet, vv ...), và đã được khoảng từ những ngày Java 1.1 cho các trường hợp như vậy mà loại giao diện không được biết hoặc được thực thi bởi giao diện khác (và do đó bạn không thể sử dụng void keyword). Java đã được thiết kế - ngoại trừ nguyên thủy và tham chiếu null - như một loại ngôn ngữ "mọi thứ là một đối tượng", một trình bao bọc giả/giữ chỗ là cần thiết để chỉ ra sự vắng mặt của các kiểu dự kiến.

Definition

Một phương pháp, theo quy định của phần method return type của JLS (§8.4.5), cần phải chính thức tuyên bố tại kiểu trả về:

Kết quả của một phương pháp kê khai hoặc kê khai các loại giá trị là phương thức trả về (loại trả về) hoặc sử dụng từ khóa void đến cho biết rằng phương thức không trả về giá trị.

Như đã đề cập trong phần JLS cho Class Literals (§15.8.2):

Loại void.class (§8.4.5) là Class<Void>

chung Sử dụng

sử dụng của nó trở nên nổi bật hơn với sự ra đời của Generics trong Java 5, vì nó cho phép định nghĩa của những giao diện để sử dụng Generics và sẽ cho phép gõ-kiểm tra việc sử dụng các giao diện và callbacks. Trước đây, đôi khi người phụ trách đã biết rằng không có đối tượng được truyền hoặc không có đối tượng trả về, ví dụ trong trường hợp khối thực hiện riêng sử dụng AccessController, thường được sử dụng trong Applet để xác định đường dẫn mã an toàn:

somemethod() { 
    // ...normal code here... 
    AccessController.doPrivileged(new PrivilegedAction<Void>() { 
     public Void run() { 
      // privileged code goes here, for example: 
      System.loadLibrary("awt"); 
      return null; // nothing to return 
     } 
    }); 
    // ...normal code here... 
} 

Lưu ý sự khác biệt với Java 1.4 version of this same code, nơi nó được không rõ ràng (và kiểu an) cho người gọi rằng không có gì được trả về:

somemethod() { 
     // ...normal code here... 
     AccessController.doPrivileged(new PrivilegedAction() { 
      public Object run() { 
       // privileged code goes here, for example: 
       System.loadLibrary("awt"); 
       return null; // nothing to return 
      } 
     }); 
     // ...normal code here... 
    } 

Đọc thêm và câu hỏi tương tự

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