2012-10-19 36 views
10

Tôi thực sự không hiểu cách các từ khóa class hoạt động trong một số trường hợp.Làm việc với từ khóa lớp trong Java

Ví dụ: phương thức get(ClientResponse.class) mất ClientResponse.class. Làm thế nào nó sử dụng điều này khi nó nhận được nó, và những lợi thế trên chỉ là đi qua một thể hiện của nó là gì?

Trả lời

10
SomeClass.class 

trả về đối tượng Lớp Java. Lớp được tổng quát hóa, vì vậy loại thực tế của SomeClass.class sẽ là Class<SomeType>.

Có rất nhiều công dụng cho đối tượng này, và bạn có thể đọc Javadoc cho nó ở đây: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html

+2

+1 để tham khảo tài liệu. Các loại thực tế trong thời gian chạy tuy nhiên là đồng bằng java/lang/Class và nó là loại chung đối số không được bảo quản do thực hiện Generics java (loại tẩy xoá). –

+0

@ KrzysztofJabłoński trong mã nếu bạn làm 'Class clazz = someClass.getClass()' nó sẽ yêu cầu bạn tham số hóa biến. là nó đúng khi nói rằng loại sẽ là Class tại thời gian biên dịch nhưng java.lang.Class khi chạy? – smcg

+0

Có. Generics được giới thiệu trong Java 5 cải thiện an toàn kiểu tại thời gian biên dịch, bằng cách giới thiệu các tham số kiểu được gọi là. Khi bạn đang thực hiện một số trình biên dịch thao tác kiểu nguy hiểm, hãy so sánh các tham số kiểu và cảnh báo bạn. Trong các tham số kiểu bytecode được thay thế bởi [bounds] của chúng (http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html) (hoặc Object khi không có) - để thông tin bị xóa. [Paper] (http://docs.oracle.com/javase/tutorial/java/generics/erasure.html) nói rằng nó được thực hiện theo cách đó trong java (không giống như đối với [ví dụ C#] (http://msdn.microsoft. com/en-us/library/512aeb7t.aspx)). –

0

Đây ClientResponse.class là một thể hiện của Class<ClientResponse>. Nói chung, đối tượng Class thể hiện loại đối tượng. Khi bạn tạo ví dụ mới:

Object obj = new ClientResponse() 

bạn có thể lấy lớp (loại) của đối tượng đó bằng cách gọi:

obj.getClass() 

Vì vậy, tại sao bạn vượt qua Class đối tượng xung quanh? Nó ít phổ biến hơn, nhưng một lý do là cho phép một số phương thức tạo số lượng tùy ý các phiên bản của một lớp cụ thể:

ClientResponse resp = ClientResponse.newInstance(); 
6

Trong ClientResponse.class, class không phải là một từ khóa, không phải là một lĩnh vực tĩnh trong lớp ClientResponse.

Từ khóa là từ khóa mà chúng tôi sử dụng để xác định một lớp trong Java. ví dụ.

public class MyClass { } /* class used here is one of the keywords in Java */ 

Các class trong ClientResponse.class là một ngắn cắt theo trường hợp của Class<T> đại diện cho lớp ClientResponse.

Có một cách khác để truy cập vào trường hợp đó mà bạn cần một phiên bản ClientResponse. ví dụ

ClientResponse obj = new ClientResponse(); 
Class clazz = obj.getClass(); 

lợi thế hơn chỉ đi qua một thể hiện của nó là gì?

Trong ví dụ trên, bạn có thể xem điều gì sẽ xảy ra trong trường hợp obj là null (một NPE). Sau đó, sẽ không có cách nào để phương thức lấy tham chiếu đến cá thể Class cho ClientResponse.

+0

Cũng có thể có một số proxy động đang diễn ra cũng như một thứ như cglib hoặc javassist. Ngoài ra, cũng có thể bạn muốn làm việc với một giao diện hoặc lớp trừu tượng, chứ không phải là loại lớp cụ thể thực tế. Bằng cách tham khảo trực tiếp lớp học, bạn rất cụ thể về những gì bạn muốn. Ngoài ra, bạn có thể ở trong một ngữ cảnh mà bạn không có một thể hiện để làm việc với: LogManager.getLogger (MyClass.class) – Matt

1

Lớp Class, khác với từ khóa class, là trường hợp mô tả siêu dữ liệu. Nó cho bạn biết về các phương thức, các thành viên dữ liệu, các nhà xây dựng và các tính năng khác của các cá thể mà bạn tạo ra bằng cách gọi new.

Ví dụ được phương pháp (ClientResponse.class) lấy ClientResponse.class như thế nào sử dụng này khi nó được nó và những gì là những lợi thế hơn chỉ đi qua một thể hiện của nó?

Bạn không thể chuyển trường hợp ClientResponse vào phương thức này; nó đang chờ siêu dữ liệu về tất cả trường hợp của ClientResponse. Nếu bạn đã thông qua một cá thể, bạn mong muốn rằng phương thức này có thể thay đổi trạng thái của cá thể đó. Nhưng việc chuyển siêu dữ liệu về tất cả các trường hợp có thể cho phép phương thức tạo một loại cá thể mới (ví dụ: proxy động) hoặc thực hiện điều gì khác phụ thuộc vào siêu dữ liệu về tất cả các phiên bản ClientResponse. Thấy sự khác biệt?

1

Lớp học là "bản thiết kế" của đối tượng. Ví dụ là một đối tượng.

Nếu chúng ta có

public class SomeClass { 
    int a; 
    SomeClass(int a) { 
     this.a = a 
    } 
} 

Chúng ta có thể có một thể hiện của lớp này

SomeClass c = new SomeClass(10); 

c là một thể hiện của lớp. Nó có một số nguyên a với giá trị 10.

Đối tượng SomeClass.class đại diện cho Class.

Đây SomeClass.class là một object loại Class trong đó có những thông tin mà SomeClass

  1. một lớp bê tông với
  2. một constructor
  3. với một thành viên biến nguyên

    và nhiều hơn nữa khác metadata về lớp học SomeClass. Lưu ý rằng nó không có giá trị cho a.

Bạn nên sử dụng get(c) trong trường hợp bạn đang có kế hoạch để làm điều gì đó với một instance của c như gọi c.a hoặc các chức năng hữu ích khác để manupulate/nhận dữ liệu của ví dụ.

Bạn nên sử dụng get(SomeClass.class) khi nhận được trả lại một cái gì đó dựa trên thực tế là đối số là một số loại lớp. Ví dụ: nếu đây là phương thức thuộc lớp học Registry có bản đồ truy xuất số implementation class dựa trên loại lớp được truyền vào.

2

Thực tế quan trọng nhất là bạn không cần phải có cá thể để gọi phương pháp. Điều này rất hữu ích trong các tình huống khi bạn không thể vì lý do nào đó khởi tạo một lớp, ví dụ: nó trừu tượng, hoặc chỉ có một hàm tạo riêng, hoặc chỉ có thể được khởi tạo một cách chính xác bởi một số khung công tác, như Spring hoặc JSF.

Sau đó, bạn có thể gọi get để lấy đối tượng thuộc loại được yêu cầu mà không biết nó đến từ đâu và cách thức tạo ra nó.

0

Bất cứ khi nào chúng tôi biên dịch bất kỳ tập tin Java, trình biên dịch sẽ nhúng một lĩnh vực public, static, final tên class, loại java.lang.Class, trong các mã byte phát ra. Vì trường này là publicstatic, chúng tôi có thể truy cập bằng cách sử dụng ký hiệu chấm chấm cùng với tên lớp như trong trường hợp của bạn là ClientResponse.class.

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