it-swarm.com.de

Wie unterscheidet sich eine Java Referenz von einem C-Zeiger?

C hat Zeiger und Java hat sogenannte Referenzen. Sie haben einige Gemeinsamkeiten in dem Sinne, dass sie alle auf etwas verweisen. Ich weiß, dass Zeiger in C die Adressen speichern, auf die sie verweisen Referenz speichern auch die Adresse? Wie unterscheiden sie sich, außer dass der Zeiger flexibler und fehleranfälliger ist?

97
Gnijuohz

Referenzen können durch Speichern der Adresse implementiert werden. Normalerweise Java Referenzen werden als implementiert Zeiger, aber das ist in der Spezifikation nicht erforderlich. Sie verwenden möglicherweise eine zusätzliche Indirektionsebene, um eine einfachere Speicherbereinigung zu ermöglichen. Am Ende läuft es jedoch (fast immer) darauf hinaus, dass (C-artige) Zeiger an der Implementierung von beteiligt sind (Java-artige) Referenzen.

Sie können keine Zeigerarithmetik mit Referenzen durchführen. Der wichtigste Unterschied zwischen einem Zeiger in C und einer Referenz in Java ist, dass Sie tatsächlich nicht zu ( und manipulieren) den zugrunde liegenden Wert einer Referenz in Java. Mit anderen Worten: Sie können keine Zeigerarithmetik durchführen.

In C können Sie einem Zeiger etwas hinzufügen (dh die Adresse) oder etwas subtrahieren, um auf Dinge zu zeigen, die "in der Nähe" sind, oder auf Orte zeigen, die sich an beliebigen befinden. -) Platz.

In Java verweist ein Verweis auf eine Sache und nur auf diese Sache. Sie können eine Variable so einstellen, dass sie eine andere Referenz enthält, aber Sie können sie nicht einfach bitten, auf "das Ding nach dem Original" zu verweisen.

Referenzen sind stark typisiert. Ein weiterer Unterschied besteht darin, dass der Typ einer Referenz viel in Java als der Typ eines Zeigers in C. In C können Sie einen int* Haben und ihn in einen char* Umwandeln und den Speicher an dieser Stelle einfach neu interpretieren Eine Neuinterpretation funktioniert in Java nicht: Sie können das Objekt nur am anderen Ende der Referenz als etwas interpretieren, das es bereits ist (dh Sie kann eine Object Referenz auf String Referenz nur dann umwandeln, wenn das Objekt, auf das gezeigt wird, tatsächlich eine String).

Diese Unterschiede machen C-Zeiger leistungsfähiger, aber auch gefährlicher. Beide Möglichkeiten (Zeigerarithmetik und Neuinterpretation der Werte, auf die verwiesen wird) erhöhen die Flexibilität von C und sind die Quelle eines Teils der Leistung der Sprache. Aber sie sind auch große Problemquellen, denn wenn sie falsch verwendet werden, können sie leicht die Annahmen brechen, dass Ihr Code aufgebaut ist. Und es ist ziemlich einfach, sie falsch zu verwenden.

142
Joachim Sauer

C++ - Referenzen sind wieder anders.

Sie müssen initialisiert werden und dürfen nicht null sein (zumindest nicht in einem wohlgeformten Programm) und können nicht erneut eingesetzt werden, um auf etwas anderes zu verweisen. Eine C++ - Referenz ähnelt eher einem Alias ​​für ein Objekt.

Ein weiterer wichtiger Unterschied zwischen Zeigern und Java/C++ - Referenzen besteht darin, dass Sie die Adresse eines Zeigers verwenden können, auf den Sie nicht zugreifen können (tatsächlich muss eine C++ - Referenz überhaupt nicht als Objekt im Speicher vorhanden sein) Zeiger auf einen Zeiger, aber keine Referenz auf eine Referenz

7
jk.

Java-Referenzen und C-Zeiger unterscheiden sich in genau zwei Punkten:

  1. Für die erstere gibt es keine Zeigerarithmetik.
  2. Und Sie können keine Java Referenz auf was auch immer Sie wollen, Sie können nur diejenigen kopieren, die an einem zugänglichen Ort gespeichert sind (statische Felder, Felder von Objekten, lokale Variablen) oder von Funktionsaufrufen zurückgegeben werden (wie Konstruktor-) Aufrufe), die sich daher alle auf Java Objekte) beziehen (niemals auf Basistypen wie Referenzen, char, int usw.).

Jemand hat geschrieben, dass Referenzen stark typisiert sind, da Sie den Compiler nicht zwingen können, einen int* Als char* Zu behandeln.
Ganz abgesehen von der Tatsache, dass diese bestimmte Konvertierung tatsächlich sicher ist gibt es in C keinen Polymorphismus, so dass der Vergleich kein Starter ist.
Natürlich ist Java ist stärker typisiert als C, nicht dass dies eine Funktion von C-Zeigern gegenüber Java Referenzen, die Sie verwenden müssen) ist die JNI, um die Typensicherheit zu brechen (abgesehen von der Missachtung generischer Einschränkungen), aber selbst in C müssen Sie den Compiler erzwingen .

Jemand schrieb, dass Java Verweise könnten als C-Zeiger implementiert werden, auf die ich sicher sage, da sie auf 32-Bit-Computern normalerweise weniger leistungsfähig sind, Wenn die JVM in C implementiert ist, sind sie auf 64-Bit-Computern normalerweise komprimierte Zeiger auf normale Objekte ("komprimierte OOPs"), um Platz und Bandbreite zu sparen.
Auf jeden Fall müssen diese C-Zeiger auch nicht den Hardwareadressen entsprechen, selbst wenn sie normalerweise (> 99% der Implementierungen) aus Leistungsgründen vorliegen.
Schließlich ist dies ein Implementierungsdetail, das dem Programmierer nicht zugänglich ist.

4
Deduplicator