2010-12-15 70 views
56
tài liệu

Java cho Class nói:đối tượng Class (java.lang.Class) là gì?

Class đối tượng được xây dựng tự động bằng Java Virtual Machine như các lớp được nạp và cuộc gọi đến các phương pháp defineClass trong class loader.

Các đối tượng Class này là gì? Chúng có giống như các đối tượng được khởi tạo từ một lớp không bằng cách gọi new?

Ngoài ra, ví dụ: object.getClass().getName() cách mọi thứ có thể được nhập thành siêu lớp Class, ngay cả khi tôi không kế thừa từ java.lang.Class?

Trả lời

71

Không có gì được nhập vào Class. Mỗi Object trong Java thuộc về một số class nhất định. Đó là lý do tại sao lớp Object, được thừa kế bởi tất cả các lớp khác, xác định phương thức getClass().

getClass(), hoặc tầm cỡ đen - Foo.class trả về một đối tượng Class, trong đó có một số siêu dữ liệu về lớp:

  • tên
  • gói
  • phương pháp
  • lĩnh vực
  • constructors
  • chú thích

và một số phương pháp hữu ích như truyền và kiểm tra khác nhau (isAbstract(), isPrimitive(), v.v ...). the javadoc cho biết chính xác thông tin nào bạn có thể có được về lớp học.

Vì vậy, ví dụ, nếu một phương pháp của anh được đưa ra một đối tượng, và bạn muốn xử lý nó trong trường hợp nó được chú thích với @Processable chú thích, sau đó:

public void process(Object obj) { 
    if (obj.getClass().isAnnotationPresent(Processable.class)) { 
     // process somehow; 
    } 
} 

Trong ví dụ này, bạn có được siêu dữ liệu về lớp của đối tượng đã cho (bất kể nó là gì) và kiểm tra xem nó có chú thích nhất định không. Nhiều người trong số các phương pháp trên một trường hợp Class được gọi là "hoạt động phản xạ", hoặc đơn giản là "phản ánh. Read here về suy nghĩ, tại sao và khi nó được sử dụng.

Cũng lưu ý rằng sự đếm và giao diện cũng đại diện cho một đối tượng Class, và có . metadata tương ứng

để tóm tắt - từng đối tượng trong java đã (thuộc) một lớp, và có một đối tượng tương ứng Class, trong đó có siêu dữ liệu về nó, có thể truy cập trong thời gian chạy

+26

Và thật thú vị khi nghĩ về điều này hơn nữa. Lớp 'Class' kế thừa từ' Object'. 'Class.class' trả về một đối tượng' Class' đại diện cho lớp 'Class'. Bạn có thể suy ngẫm về sự phản chiếu. ASPLODE HEAD CỦA TÔI. – cdhowie

+0

@cdhowie Không sử dụng Ruby nhiều, phải không? :-) –

+1

@pst: Tôi có. Nó khiến tôi muốn làm tổn thương người khác.Bất kỳ ngôn ngữ/khuôn khổ nào với [nhiều người này] (http://ruby-doc.org/core/classes/Object.html) phương pháp trên loại gốc của nó xứng đáng được chôn cất. Nó có hội chứng tack-random-crap-on-the-API-without-any-forethought theo phong cách PHP. Cue ngọn lửa ... – cdhowie

7

getClass() là một phương pháp đó. trả về một đối tượng là Ví dụ của java.lang.Class ... không có quá trình truyền liên quan. Quá trình truyền sẽ giống như sau:

Class<?> type = (Class<?>) object; 
34

Đối tượng lớp là một đối tượng meta mô tả lớp của đối tượng.Nó được sử dụng chủ yếu với khả năng phản chiếu của Java. Bạn có thể nghĩ về nó như một "kế hoạch chi tiết" của lớp thực tế. Ví dụ. bạn có một lớp Xe như thế này:

public class Car { 
    public String brand; 
} 

Sau đó bạn có thể xây dựng đối tượng Lớp mô tả lớp "Xe hơi" của bạn.

Class myCarClass = Class.forName("Car"); 

Bây giờ bạn có thể làm tất cả các loại truy vấn trên lớp xe của bạn trên mà đối tượng Class:

myCarClass.getName() - returns "Car" 
myCarClass.getDeclaredField("brand") - returns a Field object describing the "brand" field 

và vân vân. Mỗi đối tượng java có một phương thức getClass() trả về đối tượng Class mô tả Lớp của đối tượng Java. Vì vậy, bạn có thể làm điều gì đó như:

Car myCar = new Car(); 
Class myCarClass = myCar.getClass(); 

Điều này cũng làm cho các đối tượng bạn không biết, ví dụ như các đối tượng bạn nhận được từ bên ngoài:

public void tellMeWhatThisObjectsClassIs(Object obj) { 
    System.out.println(obj.getClass().getName()); 
} 

Bạn có thể ăn phương pháp này bất kỳ đối tượng java và nó sẽ in lớp thực tế của đối tượng mà bạn đã cho nó.

Khi làm việc với Java, hầu hết thời gian bạn không cần lo lắng về các đối tượng Lớp học. Họ có một số trường hợp sử dụng tiện dụng mặc dù. Ví dụ. chúng cho phép bạn lập trình instanciate đối tượng của một lớp nhất định, được sử dụng thường xuyên cho serialization đối tượng và deserialization (ví dụ như chuyển đổi Java Objects để XML và ngược lại, cũng chủ yếu là trở lại).

Class myCarClass = Class.forName("Car"); 
Car myCar = myCarClass.newInstance(); // is roughly equivalent to = new Car(); 

Bạn cũng có thể sử dụng nó để tìm hiểu tất cả các trường hoặc phương thức đã khai báo của lớp học của bạn, rất hữu ích trong một số trường hợp nhất định. Vì vậy, ví dụ: nếu phương pháp của bạn được truyền một đối tượng không xác định và bạn cần biết thêm về nó, như thể nó bổ sung một số giao diện, vv, lớp Class là bạn của bạn ở đây.

Vì vậy, câu chuyện dài ngắn, lớp, trường, phương pháp, vv. Các lớp trong gói java.lang.reflect cho phép bạn phân tích các lớp, phương thức, trường đã xác định của bạn, tạo các phiên bản mới các loại công cụ khác và chúng cho phép bạn thực hiện điều này một cách linh hoạt khi chạy.

+0

Class c1 = Car.class; "Lớp" này là gì? nó là một biến công cộng tồn tại trong mỗi lớp? –

+4

Về cơ bản nó là cú pháp đường. Nó là một cái gì đó trình biên dịch đánh giá một cái gì đó mà tải đối tượng lớp với tên đã cho. Tương đương với Class.forName ("tên lớp đầy đủ") nhưng lớp được kiểm tra để tồn tại trong thời gian biên dịch trong khi Class.forName() được thực thi khi chạy. –

2

Đối tượng Lớp là một phiên bản của Lớp (java.lang.Class). Dưới đây trích dẫn từ javadoc của lớp học nên trả lời câu hỏi của bạn

Lớp không có hàm tạo công khai. Thay vào đó các đối tượng Class được xây dựng tự động bởi Máy ảo Java vì các lớp được nạp và các cuộc gọi đến phương thức defineClass trong trình nạp lớp.

4

Tôi cũng muốn thêm vào câu trả lời của ColinD rằng getClass sẽ trả về cùng một đối tượng cho các trường hợp cùng loại. Điều này sẽ in đúng:

MyOtherClass foo = new MyOtherClass(); 
    MyOtherClass bar = new MyOtherClass(); 
    System.out.println(foo.getClass()==bar.getClass()); 

Lưu ý rằng nó không phải là bằng, Tôi đang sử dụng ==.

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