Đối tượng Class (java.lang.Class) là gì?


81

Tài liệu Java cho Classbiết:

Classcác đối tượng được Máy ảo Java xây dựng tự động khi các lớp được tải và bằng các cuộc gọi đến defineClassphương thức trong trình tải lớp.

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

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

Câu trả lời:


97

Không có gì được đánh máy cho Class. Mọi Objecttrong Java đều thuộc về một nhất định class. Đó là lý do tại sao Objectlớp, được kế thừa bởi tất cả các lớp khác, định nghĩa getClass()phương thức.

getClass()hoặc class-Lite - Foo.classtrả về một Classđối tượng, chứa một số siêu dữ liệu về lớp:

  • Tên
  • gói hàng
  • phương pháp
  • lĩnh vực
  • người xây dựng
  • chú thích

và một số phương pháp hữu ích như đúc và kiểm tra khác nhau ( isAbstract(), isPrimitive(), vv). javadoc hiển thị chính xác thông tin bạn có thể lấy về một lớp.

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

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ó một chú thích nhất định hay không. Nhiều phương thức trên một Classphiên bản được gọi là "hoạt động phản chiếu" hoặc đơn giản là "phản chiếu. Đọc ở đây về phản xạ, tại sao và khi nào nó được sử dụng.

Cũng lưu ý rằng Classđối tượng đại diện cho enums và intefaces cùng với các lớp trong ứng dụng Java đang chạy và có siêu dữ liệu tương ứng.

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


37
Và thật vui khi nghĩ về điều này xa hơn. Các Classlớp kế thừa từ Objectchính nó. Class.classtrả về một Classđối tượng đại diện cho Classlớp. Bạn có thể phản ánh về sự phản chiếu. ĐẦU CỦA TÔI ASPLODE.
cdhowie

1
@pst: Tôi có. Nó khiến tôi muốn làm tổn thương mọi người. Bất kỳ ngôn ngữ / khuôn khổ nào có nhiều phương thức này trên loại gốc của nó đều đáng bị chôn vùi. Nó có hội chứng tack-ngẫu nhiên-crap-vào-API-không-có-bất-kỳ-tính-theo-phong cách PHP. Cue ngọn lửa ...
cdhowie

1
Lớp c1 = Car.class; "Lớp" này là gì? nó có phải là một biến công khai tồn tại trong mọi lớp không?
david blaine

1
Theo một cách nào đó, có. Trên thực tế, đó là một "lớp nghĩa đen" - đó là cách bạn tham chiếu đến đối tượng Lớp theo tên.
Bozho

1
@cdhowie Bình luận của bạn đã châm biếm từ 'lớp' đối với tôi về mặt ngữ nghĩa.
stillanoob

44

Đối tượng Lớp là một loại đối tượng meta mô tả lớp của một đối tượng. Nó được sử dụng hầu hết với khả năng phản chiếu của Java. Bạn có thể coi nó giống như một "bản thiết kế" của lớp thực tế. Vd: bạn có một chiếc xe đẳng cấp như thế này:

public class Car {
    public String brand;
}

Sau đó, bạn có thể tạo một đối tượng Lớp mô tả lớp "Xe" của bạn.

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

Bây giờ bạn có thể thực hiện tất cả các loại truy vấn trên lớp Xe của mình trên đối tượng Lớp đó:

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

và như thế. Mọi đối tượng java đều có một phương thức getClass () trả về đối tượng Lớp 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 hoạt động đối với các đối tượng bạn không biết, ví dụ: các đối tượng bạn lấy từ bên ngoài:

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

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

Khi làm việc với Java, hầu hết thời gian bạn không cần phải lo lắng về các đối tượng Class. Tuy nhiên, chúng có một số trường hợp sử dụng tiện dụng. Ví dụ: chúng cho phép bạn cài đặt theo chương trình các đối tượng của một lớp nhất định, được sử dụng thường xuyên để tuần tự hóa và giải mã hóa đối tượng (ví dụ: chuyển đổi các Đối tượng Java qua lại sang / từ XML hoặc JSON).

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 ra tất cả các trường hoặc phương thức đã khai báo của lớp, v.v., điều này 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 thức của bạn nhận được một đối tượng không xác định và bạn cần biết thêm về nó, chẳng hạn như nếu nó thực thi một số giao diện, v.v., thì lớp Class là bạn của bạn ở đây.

Tóm lại, các lớp Class, Field, Method, v.v. nằm 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 mình, tạo phiên bản mới của chúng, gọi phương thức tất cả các loại nội dung 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 trong thời gian chạy.


1
Lớp c1 = Car.class; "Lớp" này là gì? nó có phải là một biến công khai tồn tại trong mọi lớp không?
david blaine

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

8

getClass()là một phương thức trả về một đối tượng là một thể hiện của java.lang.Class... không có liên quan đến quá trình ép kiểu. Quá trình truyền sẽ trông như thế này:

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

6

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 true :

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

Lưu ý rằng nó không phải equals, tôi đang sử dụng ==.


3

Đối tượng Class là một thể hiện của Class (java.lang.Class). Dưới đây trích dẫn từ javadoc của lớp 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 Lớp được Máy ảo Java xây dựng tự động khi các lớp được tải và bằng các lệnh gọi đến phương thức defineClass trong trình nạp lớp.


2

Để hiểu đầy đủ đối tượng lớp, hãy quay lại và hiểu chúng ta lấy đối tượng lớp ở vị trí đầu tiên. Bạn thấy đấy, mỗi .javatệp bạn tạo, khi bạn biên dịch .javatệp đó , jvm sẽ tạo một .classtệp, tệp này chứa tất cả thông tin về lớp, cụ thể là:

  1. Tên đủ điều kiện của lớp
  2. Phụ huynh của lớp
  3. Thông tin phương pháp
  4. Trường biến
  5. Constructor
  6. Thông tin bổ trợ
  7. Hồ bơi liên tục

Danh sách bạn thấy ở trên là những gì bạn thường thấy trong một lớp học thông thường. Bây giờ, cho đến thời điểm này, .javatệp và .classtệp của bạn tồn tại trên đĩa cứng của bạn, khi bạn thực sự cần sử dụng lớp tức là thực thi mã trong main()phương thức, jvm sẽ sử dụng .classtệp đó trong ổ cứng của bạn và tải nó vào một trong 5 bộ nhớ. vùng trong jvm, là vùng phương thức, ngay sau khi tải .classtệp vào vùng phương thức, jvm sẽ sử dụng thông tin đó và một đối tượng Lớp đại diện cho lớp đó tồn tại trong vùng bộ nhớ heap.

Đây là chế độ xem cấp cao nhất,

.java--compile -> .class-> khi bạn thực thi script -> .classtải vào vùng phương thức --jvm tạo đối tượng lớp từ vùng phương thức -> một đối tượng lớp được sinh ra

Với một đối tượng lớp, bạn có được thông tin như tên lớp và tên phương thức, mọi thứ về lớp.

Cũng cần lưu ý, sẽ chỉ có một đối tượng lớp cho mọi lớp bạn sử dụng trong tập lệnh.

Hy vọng điều này có ý nghĩa


điểm bổ sung tốt. một nhận xét về từ ngữ, tôi không biết chủ đề tốt để tự chỉnh sửa "jvm sẽ sử dụng thông tin đó một đối tượng Lớp đại diện cho lớp đó tồn tại trong vùng bộ nhớ heap." trông không đúng, dòng sau bằng -> trông logic hơn. Tôi có ở đây không? xin vui lòng nhất quán, cảm ơn bạn!
Alexei Martianov

1

Lớp Object là lớp cha của tất cả các lớp trong java theo mặc định. Nói cách khác, nó là lớp cao nhất của java.

Lớp Object có lợi nếu bạn muốn tham chiếu đến bất kỳ đối tượng nào có kiểu mà bạn không biết. Lưu ý rằng biến tham chiếu lớp cha có thể tham chiếu đến đối tượng lớp con, được gọi là upcasting.

Hãy lấy một ví dụ, có phương thức getObject () trả về một đối tượng nhưng nó có thể thuộc bất kỳ kiểu nào như Nhân viên, Sinh viên, v.v., chúng ta có thể sử dụng tham chiếu lớp Đối tượng để tham chiếu đối tượng đó. Ví dụ:

Object obj=getObject(); // chúng tôi không biết đối tượng nào sẽ được trả về từ phương thức này

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.