Java nie jest monolitem, wprost przeciwnie składa się z szeregu klas definiujących obiekty różnego typu. Dla przejrzystości klasy te pogrupowane są w środku hierarchicznie ułożone pakiety. Każdy splot grupuje klasy związane z pewnym szerokim zakresem zastosowań języka np. java.io (klasy wejścia-wyjścia), java.util.prefs (klasy użytkowe do obsługi preferencji) oznacza to java.awt (system obsługi trybu graficznego). Hierarchię klas oddają nazwy pakietów, które skonstruowane są też jako ścieżki dostępu do plików. Na przypadek zbiór Preferences znajdująca się wewnątrz pakiecie java.util.prefs ma pełną nazwę: java.util.prefs.Preferences, co oznacza:
Dzięki takiemu systemowi nazwy klas są niepowtarzalne, co pozwala zniknąć niejednoznaczności (np. lub chodzi o klasę List implementującą strukturę listy danych lub o List implementującą graficzną listę wyświetlaną do wnętrza okienku).
Wszystkie klasy pisane wskroś programistów niezależnych powinny znajdować się umieszczane do wnętrza innych hierarchiach. Firma Sun w szeregu przypadków zaleca, żeby w środku nazewnictwie klas niestandardowych poprzednio właściwą nazwą pakietu używać odwróconą nazwę domeny internetowej autora pakietu. Na przypadek urządzenie Ant znajduje się w środku pakiecie org.apache.ant, co zapobiega konfliktom nazw z pakietami innych autorów, którzy też chcieliby wymienić osobisty wiązka Ant.
Domyślnie klasy pakietu nie są możliwe do użycia pozycja nim. Stąd nie występują konflikty nazw klas wobec
imporcie różnych pakietów. Klasa pakietu staje się publiczną poniżej deklaracji public class Foo.