co to jest obiekt klasy (java.lang.Class)?

82

Dokumentacja Java dla Classmówi:

Classobiekty są konstruowane automatycznie przez wirtualną maszynę języka Java podczas ładowania klas i przez wywołania defineClassmetody w programie ładującym klasy.

Co to za Classobiekty? Czy są one tym samym, co obiekty tworzone z klasy przez wywołanie new?

Na przykład, w object.getClass().getName()jaki sposób wszystko może zostać wpisane na maszynie do nadklasy Class, nawet jeśli nie dziedziczę po java.lang.Class?

Karbonizator
źródło

Odpowiedzi:

97

Nic nie jest pisane na maszynie Class. Każdy Objectw Javie należy do pewnego class. Dlatego Objectklasa, która jest dziedziczona przez wszystkie inne klasy, definiuje getClass()metodę.

getClass()lub literał klasy - Foo.classzwraca Classobiekt, który zawiera metadane dotyczące klasy:

  • Nazwa
  • pakiet
  • metody
  • pola
  • konstruktorzy
  • adnotacje

i Użyteczne sposoby, takie jak odlewanie i różne kontroli ( isAbstract(), isPrimitive()itp). javadoc pokazuje dokładnie, jakie informacje o klasie można uzyskać.

Na przykład, jeśli twoja metoda otrzyma obiekt i chcesz go przetworzyć na wypadek, gdyby została opatrzona @Processableadnotacją, to:

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

W tym przykładzie uzyskujesz metadane dotyczące klasy danego obiektu (cokolwiek to jest) i sprawdzasz, czy ma on daną adnotację. Wiele metod na Classinstancji nazywa się „operacjami refleksyjnymi” lub po prostu „refleksją. Przeczytaj tutaj o refleksji, dlaczego i kiedy jest używana.

Należy również zauważyć, że Classobiekt reprezentuje wyliczenia i interfejsy wraz z klasami w uruchomionej aplikacji Java i ma odpowiednie metadane.

Podsumowując - każdy obiekt w java ma (należy do) klasę i ma odpowiedni Classobiekt, który zawiera o nim metadane, który jest dostępny w czasie wykonywania.

Bozho
źródło
37
I fajnie jest dalej o tym myśleć. ClassKlasa dziedziczy po Objectsobie. Class.classzwraca Classobiekt, który reprezentuje Classklasę. Możesz zastanowić się nad refleksją. MY HEAD ASPLODE.
cdhowie
1
@pst: Mam. To sprawia, że ​​chcę skrzywdzić ludzi. Każdy język / framework z tak wieloma metodami w swoim typie głównym zasługuje na to, by zostać pochowany. Ma w stylu PHP zespół tack-random-crap-to-the-API-without-any-forethought. Cue the flames ...
cdhowie,
1
Klasa c1 = Car.class; Co to za „klasa”? czy jest to zmienna publiczna, która istnieje w każdej klasie?
david Blaine
1
W pewnym sensie tak. W rzeczywistości jest to „literał klasy” - w ten sposób odwołujesz się do obiektu Class przez nazwę.
Bozho
1
@cdhowie Twój komentarz semantycznie zaspokoił dla mnie słowo „klasa”.
stillanoob
44

Obiekt Class jest rodzajem meta obiektu opisującego klasę obiektu. Jest używany głównie z możliwościami odbicia w Javie. Możesz myśleć o tym jak o „planie” aktualnej klasy. Np. Masz taki samochód klasy:

public class Car {
    public String brand;
}

Następnie możesz skonstruować obiekt Class, który opisuje Twoją klasę „Car”.

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

Teraz możesz wykonywać różnego rodzaju zapytania dotyczące klasy samochodu w tym obiekcie klasy:

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

i tak dalej. Każdy obiekt Java ma metodę getClass (), która zwraca obiekt Class opisujący klasę obiektu Java. Możesz więc zrobić coś takiego:

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

Działa to również w przypadku obiektów, których nie znasz, np. Obiektów, które dostałeś z zewnątrz:

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

Możesz przesłać tę metodę do dowolnego obiektu Java, a wydrukuje ona aktualną klasę obiektu, który jej przekazałeś.

Podczas pracy z Javą w większości przypadków nie musisz martwić się o obiekty Class. Mają jednak kilka przydatnych przypadków użycia. Np. Pozwalają na programistyczne instancjowanie obiektów określonej klasy, która jest często używana do serializacji i deserializacji obiektów (np. Konwertowanie obiektów Java w obie strony do / z XML lub JSON).

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

Możesz go również użyć do znalezienia wszystkich zadeklarowanych pól lub metod swojej klasy itp., Co jest bardzo przydatne w niektórych przypadkach. Na przykład, jeśli twoja metoda otrzyma nieznany obiekt i musisz wiedzieć o nim więcej, na przykład jeśli zawiera jakiś interfejs itp., Klasa Class jest tutaj twoim przyjacielem.

Krótko mówiąc, klasy Class, Field, Method itp., Które znajdują się w pakiecie java.lang.reflect, pozwalają analizować zdefiniowane przez Ciebie klasy, metody, pola, tworzyć nowe ich instancje, wywoływać metody wszelkiego rodzaju innych rzeczy i pozwalają ci to robić dynamicznie w czasie wykonywania.

Jan Thomä
źródło
1
Klasa c1 = Car.class; Co to za „klasa”? czy jest to zmienna publiczna, która istnieje w każdej klasie?
david Blaine
5
Zasadniczo jest to cukier syntaktyczny. Jest to coś, co kompilator ocenia jako coś, co ładuje obiekt klasy o podanej nazwie. W przybliżeniu odpowiednik Class.forName („w pełni kwalifikowana nazwa klasy”), ale klasa jest sprawdzana pod kątem istnienia w czasie kompilacji, podczas gdy Class.forName () jest wykonywana w czasie wykonywania.
Jan Thomä
8

getClass()jest metodą, która zwraca obiekt, który jest instancją java.lang.Class... bez rzutowania. Casting wyglądałby tak:

Class<?> type = (Class<?>) object;
ColinD
źródło
7

Chciałbym również dodać do odpowiedzi ColinD, że getClass zwróci ten sam obiekt dla instancji tego samego typu. To wydrukuje prawda :

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

Zauważ, że tak nie jest equals, używam ==.

Koray Tugay
źródło
3

Obiekt Class jest instancją klasy Class (java.lang.Class). Poniższy cytat zaczerpnięty z javadoc klasy powinien odpowiedzieć na Twoje pytanie

Klasa nie ma publicznego konstruktora. Zamiast tego obiekty klasy są konstruowane automatycznie przez wirtualną maszynę języka Java podczas ładowania klas i przez wywołania metody defineClass w module ładującym klasy.

Pakka Techie
źródło
2

Aby w pełni zrozumieć obiekt klasy, cofnijmy się i zrozummy, że w pierwszej kolejności otrzymujemy obiekt klasy. Widzisz, każdy .javautworzony plik, kiedy kompilujesz ten .javaplik, jvm utworzy .classplik, ten plik zawiera wszystkie informacje o klasie, a mianowicie:

  1. W pełni kwalifikowana nazwa klasy
  2. Rodzic klasy
  3. Informacje o metodzie
  4. Zmienne pola
  5. Konstruktor
  6. Informacje modyfikujące
  7. Stały basen

Lista, którą widzisz powyżej, jest tym, co zazwyczaj widzisz na typowych zajęciach. Teraz, do tego momentu, twój .javaplik i .classplik istnieje na twoim twardym dysku, kiedy faktycznie potrzebujesz użyć klasy, tj. Wykonać kod w main()metodzie, jvm użyje tego .classpliku na twoim twardym dysku i załaduje go do jednej z 5 pamięci obszary w jvm, który jest obszarem metody, natychmiast po załadowaniu .classpliku do obszaru metody jvm użyje tych informacji i obiektu Class, który reprezentuje tę klasę, która istnieje w obszarze pamięci sterty.

Oto widok najwyższego poziomu,

.java--compile -> .class-> kiedy wykonujesz skrypt -> .classładuje do obszaru metody - jvm tworzy obiekt klasy z obszaru metody -> rodzi się obiekt klasy

Za pomocą obiektu klasy uzyskujesz informacje, takie jak nazwa klasy i nazwy metod, wszystko o klasie.

Należy również pamiętać, że dla każdej klasy używanej w skrypcie będzie tylko jeden obiekt klasy.

Mam nadzieję, że to ma sens

Brendon Cheung
źródło
dobre dodatkowe punkty. jedna uwaga na temat sformułowań, nie znam tematu, który dobrze się redaguje "jvm użyje tej informacji i obiektu Class, który reprezentuje tę klasę, która istnieje w obszarze pamięci sterty." wygląda nieprawidłowo, wiersz później z -> wygląda bardziej logicznie. Jestem tutaj? proszę zachować spójność, dziękuję!
Alexei Martianov
@Brendon Cheung, kiedy powiedziałeś „obiekt klasy, który reprezentuje tę klasę” , jest to klasa, a nie instancja tej klasy, więc myślę, że powinniśmy zmodyfikować wyrażenie. Ponieważ tylko „instancje” trafiają do pamięci sterty, a nie ich klasa.
starriet
1

Klasa Object jest domyślnie klasą nadrzędną wszystkich klas w Javie. Innymi słowy, jest to najwyższa klasa java.

Klasa Object jest korzystna, jeśli chcesz odwołać się do dowolnego obiektu, którego typu nie znasz. Zauważ, że zmienna referencyjna klasy nadrzędnej może odnosić się do obiektu klasy potomnej, znanej jako upcasting.

Weźmy przykład, istnieje metoda getObject (), która zwraca obiekt, ale może być dowolnego typu, np. Employee, Student itp., Możemy użyć odwołania do klasy Object, aby odnieść się do tego obiektu. Na przykład:

Object obj=getObject(); // nie wiemy, jaki obiekt zostanie zwrócony z tej metody

Ishanka Abeysinghe
źródło