2015-06-24 23 views
7

Kiedy wywołujemy polecenie java za pomocą polecenia -cp, dostarczamy niektóre katalogi i pliki jar. Czy jvm wczytuje wszystkie klasy wymienione przez ścieżkę klasy Czy jest to po prostu super zestaw wszystkich klas, które jvm będzie ładowało się w razie potrzeby?Czy jvm wczytuje wszystkie klasy wymienione przez ścieżkę klas?

+0

Tytuł zawiera słowo ClassLoader, ale twoje pytanie o tym nie wspomina. Czy zapomniałeś zadać część swojego pytania? – immibis

+0

@immibis * Czy jvm wczytuje wszystkie klasy wymienione przez ścieżkę klasy * – CKing

+0

Dzięki Chetan, zredagowałem pytanie. – hsingh

Odpowiedz

7

chce się załadować JVM wszystkich klas wymienionych przez ścieżce klasy A jest to tylko super zbiór wszystkich klas, które będą wyglądać JVM do ładowania, gdy wymagane ?

JVM ładuje klasy z danej klasy, w zależności od potrzeb, tzn. Po znalezieniu odnośnika dla klasy jest ładowana. Istnieje również hierarchia ładowań klas w JVM, klasa ładowana przez moduł ładujący klasy macierzystej jest używana przez ładowarki niższej klasy.

+0

Napisałem prostą klasę HelloWorld, która nie importuje ani nie używa żadnego innego słoika innej firmy. Kiedy uruchomię to z "java -verbose: class HelloWorld", to widzę, że tyle klas z rt.jar jest ładowanych przez JVM. Nadal nie rozumiem dla klas core java ładowanych przez program ładujący Bootstrap. Czy wszystkie klasy zostały załadowane z pliku rt.jar? – hsingh

+0

@hsingh JVM wymaga klas obecnych w rt.jar do ustawienia środowiska wykonawczego java. Nie jestem pewien, czy wszystkie klasy, ale z pewnością niektóre są ładowane z rt.jar –

0

Ładowanie klas odbywa się w kolejności i wygląda w lokalizacjach. -cp należy do trzeciej kategorii wymienionej poniżej. Zazwyczaj klasy aplikacji powinny być dostarczane za pośrednictwem -cp lub będą szukać zmiennej środowiskowej CLASSPATH.

Ramy rozszerzeń korzystają z mechanizmu delegowania klas. Gdy środowisko wykonawcze musi załadować nową klasę do wniosku, że wygląda dla klasy w następujących miejscach, w kolejności:

1) Bootstrap klasy: klas wykonania w rt.jar, zajęcia internacjonalizacji w i18n .jar i inne.

2) zainstalowanych rozszerzeń: klas w plikach JAR w katalogu lib/ext na JRE i na platformy określonego katalogu rozszerzeń całego systemu (na przykład/usr/jdk/packages/lib/ext w systemie operacyjnym Solaris ™, ale pamiętaj, że użycie tego katalogu dotyczy tylko Java ™ 6 i nowszych).

3) Ścieżka klas: klas, w tym klas w plikach JAR, na ścieżkach określonych przez właściwość systemową java.class.path. Jeśli plik JAR na ścieżce klasy ma manifest z atrybutem Class-Path, przeszukiwane będą również pliki JAR określone przez atrybut Class-Path. Domyślnie właściwość java.class.path ma wartość., Bieżący katalog. Możesz zmienić wartość, używając opcji wiersza poleceń -classpath lub -cp lub ustawiając zmienną środowiskową CLASSPATH. Opcje wiersza polecenia zastępują ustawienie zmiennej środowiskowej CLASSPATH.

https://docs.oracle.com/javase/tutorial/ext/basics/load.html

+1

Więc '-cp' powoduje automatyczne ładowanie klas? – CKing

+0

-cp jest ścieżką klas, pokazującą środowisku wykonawczemu ścieżkę, w której może znaleźć wymagane klasy, które nie znajdują się w dwóch pierwszych lokalizacjach (rt.jar i rozszerzenia). jeśli żądana klasa nie zostanie znaleziona w żadnej z trzech lokalizacji zakończy się wyjątkiem classnotfound – KDP

+0

Pytanie nie dotyczy działania '-cp' ani sposobu w jaki klasy są wyszukiwane. Pytanie brzmi, czy klasy/słoiki wyszczególnione w '-cp' są ładowane automatycznie. Twoja odpowiedź wyjaśnia kolejność przeszukiwania klas. To nie jest to, o co poprosił PO. Jedyną częścią twojej odpowiedzi, która mówi o ładowaniu, jest * Ładowanie klasy następuje w kolejności *, która nie odpowiada na pytanie. – CKing

0

To nie ładuje wszystkie klasy, ale nie wie, gdzie ich szukać, gdy są potrzebne.

Zostaną załadowane, gdy będą potrzebne w pierwszej kolejności.

1

Istnieją dwie koncepcje zaangażowany

  • ładowania
  • inicjalizacji

Inicjowanie klasy zainicjuje pól i wykonać bloki statyczne. Dokładny moment, w którym tak się dzieje jest ważny dla semantyki aplikacji, dlatego jest to precisely defined.

Inicjalizacja wymaga najpierw załadowania; ale ładowanie jest bardziej wewnętrzną koncepcją JVM.JVM może i jest dozwolone, agresywnie preload klasy, nawet jeśli niepotrzebne. Ten proces nie wpływa na semantykę aplikacji i jest niewidoczny dla aplikacji.

Jeśli chodzi o wniosek, klasa musi zostać załadowana, jeśli otrzymamy obiekt o numerze Class, np. od Foo.class, Class.forName lub innych interfejsów API do refleksji. Możemy zbadać właściwości Class bez konieczności inicjowania inicjalizacji.

Jedno ważne ograniczenie - musimy uzyskać ten sam obiekt Class dla tej samej nazwy klasy (i tego samego programu ładującego klasy). Obiekt Class jest reprezentacją obciążonej klasy.

+0

W odniesieniu do ostatniego punktu, nie sądzę, że obiekt "Class" ** potrzebuje **, aby był taki sam. Myślę, że to po prostu dobra praktyka dla implementacji. Musisz to znaleźć w JLS. –

+0

Tak, [_ Podaj to samo imię, dobry program ładujący klasy powinien zawsze zwracać ten sam obiekt klasy.] (Http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html# jls-12.2) O ile się nie mylę. –

+1

@SotiriosDelimanolis - nie dobry program ładujący klasy może nawet zwrócić nieprawidłowy obiekt klasy! Myślę, że zdanie oznacza, że ​​ładunek klasy "legit" powinien zachowywać się w ten sposób. Istnieje wiele wzmianek o "* obiekcie klasy *" w JLS i javadocs, np. 'statyczna synchronizacja' działa na" obiekcie klasy "; nie ma większego sensu, jeśli mogą istnieć 2 obiekty klasy dla klasy. Poza tym 'Class' nie zastępuje' równa się' i jest mnóstwo kodu używając '==' bezpośrednio do sprawdzania równości klas, nawet w przykładach w JLS. – ZhongYu

1
  1. JVM ładuje tylko odwołuje zajęcia i nie każda klasa obecny w słoikach w ścieżce klas
  2. Ładowanie zajęć odbywa się poprzez sposób hierarchiczny
  3. zbyt wielu słoików w ścieżce klasy zajmuje tylko więcej miejsca na dysku
  4. JVM wykorzystuje tylko pamięć w pamięci fizycznej (RAM).
Powiązane problemy