Referencje można zaimplementować, przechowując adres. Zazwyczaj odniesienia do Java będą implementowane jako wskaźniki, ale nie jest to wymagane przez specyfikację. Mogą używać dodatkowej warstwy pośredniej, aby ułatwić zbieranie śmieci. Ale ostatecznie (prawie zawsze) sprowadza się do wskaźników (w stylu C) zaangażowanych w implementację odniesień (w stylu Java).
Nie można wykonywać arytmetyki wskaźników za pomocą referencji. Najważniejszą różnicą między wskaźnikiem w C a referencją w Javie jest to, że nie można faktycznie uzyskać (i manipulować) wartości bazowej referencji w Javie. Innymi słowy: nie można wykonywać arytmetyki wskaźników.
W C możesz dodać coś do wskaźnika (tj. Adres) lub odjąć coś, aby wskazać rzeczy „w pobliżu” lub wskazać miejsca, które są w dowolnym miejscu.
W Javie odwołanie wskazuje tylko na jedną rzecz. Możesz sprawić, by zmienna zawierała inne odwołanie, ale nie możesz po prostu poprosić o wskazanie „rzecz po rzeczy oryginalnej”.
Referencje są mocno wpisane. Inną różnicą jest to, że typ odwołania jest znacznie bardziej ściśle kontrolowany w Javie niż typ wskaźnika w C. W C możesz mieć int*
i rzutować na char*
ai po prostu ponownie interpretować pamięć w tym miejscu. Ta reinterpretacja nie działa w Javie: możesz interpretować obiekt na drugim końcu referencji jako coś, co już jest (tzn. Możesz rzutować Object
referencję na String
referencję tylko wtedy, gdy wskazany obiekt to a String
).
Różnice te sprawiają, że wskaźniki C są silniejsze, ale także bardziej niebezpieczne. Obie te możliwości (arytmetyka wskaźnika i reinterpretacja wskazywanych wartości) zwiększają elastyczność C i są źródłem pewnej potęgi języka. Ale są również dużymi źródłami problemów, ponieważ jeśli użyte nieprawidłowo, mogą łatwo złamać założenia, na których opiera się Twój kod. I jest to dość łatwe w użyciu ich nieprawidłowo.