Cześć,
Zgłębiam tajemnicę podstaw działania aplikacji od momentu kompilacji do działania i potrzebuje kilku wyjaśnień w celu zrozumienia tematu, ale po kolei :
Definicje :
-
JDK - środowisko odpowiedzialne za kompilację kodu
-
JRE - środowisko uruchomieniowe
-
JVM - środowisko działania
-
Na początku działa JDK kompilując nasze klasy Java do kodu maszynowego dla środowiska JVM. Tworzony jest również Manifest zawierający listę klas oraz klasę uruchomieniową (nie jestem pewien). Docelowo podczas kompilacji generyki mają typ Object (tego też nie jestem pewien).
-
Podczas ładowania działamy w środowisku JRE gdzie ładowane są wszystkie klasy poprzez ClassLoader i tutaj również działa linker, który wykonuje wiązanie wczesne - lokalnych zmiennych, metod, klas statycznych itd. itp. oraz wiązanie późne podczas wykonywania programu dla wszystkich obiektów (tworzonych dynamicznie przez new), metod i klas parametryzowanych, interfejsów i dziedziczonych klas jest to wykonywane w czasie działania programu (JUST IN TIME). Następnie przygotowywany jest główny wątek (Main ) oraz obiekty w uruchamiane w metodzie, które wrzucane są do pamięci (referencje oraz primitywy do stack , obiekty do cheap).
-
Podczas działania programu zarządzamy pamięcią i uruchamiane są nowe wątki (jeśli istnieją) oraz obiekty które wrzucane są do pamięci i w tym czasie wiemy jakiego typu są klasy, metody generyczne oraz obiekty dziedziczące interfejsy lub klasy.
Przykład :
Mając tablicę int[] tablica = new tab[3];
- Klasa z tą tablicą jest kompilowana do kodu maszynowego.
- Podczas ładowania klasa jest ładowana do pamięci i następuje wiązanie typów. W sytuacji gdy nie można stwierdzić typu mamy exception - ArrayStoreException stąd nie moża używać typów parametryzowanych bo są one wiązane podczas wykonania
Przykład drugi :
//pseudo kod
Mając klasy :
interface Parent {
public void parentVoice();
}
class Child implements Parent{
public void childVoice();
}
Potem w main tworzymy Parent p = new Child();
p.childVoice();
- Klasy są kompilowane do kodu maszynowego
- Podczas ładowania wykonywane jest wiązanie klas - z racji tego ze nie znamy typu tworzonego obiekty wiązanie następuje podczas fazy wykonania, a referencja p wiąże metody klasy Parent. Błąd następuje podczas wykonania programu przy odwołaniu p.childVoice()
Proszę o sugestie i podpowiedzi. Ze względu na rozległość tematu nie potrzebuje szczegółów dotyczących kompilatora, ładowania i wykonania (chyba, że uznacie to za stosowne). Chciałbym zrozumieć ogół sytuacji, by wiedzieć jak działają generyki, interejsy, dziedziczenie oraz środowisko od drugiej strony - kod pisać potrafię, ale to jak lizanie cukierka przez papierek.
Pytanie urodziło się w momencie czytania tematu tworzenia tablic - można stworzyć listę tablic, ale tablicę list już niekoniecznie, właśnie ze względu na różnicę w momencie sprawdzania typu obu rodzajów.
//dzięki Shalom