C hat Zeiger und Java hat sogenannte Referenzen. Sie haben einige Gemeinsamkeiten in dem Sinne, dass sie alle auf etwas hinweisen. Ich weiß, dass Zeiger in C die Adressen speichern, auf die sie zeigen. Speichert die Referenz auch die Adresse? Wie unterscheiden sie sich, außer dass der Zeiger flexibler und fehleranfälliger ist?
97
final
Referenz in Java entspricht fast einer C ++ - Referenz. Der Grund, warum sie nicht genau gleichwertig sind, ist, dass eine C ++ - Referenz nicht nullwertfähig ist, wohingegen einefinal
Referenz in Java nullwertfähig ist.Antworten:
Referenzen können durch Speichern der Adresse implementiert werden. In der Regel werden Java-Referenzen als Zeiger implementiert, dies ist jedoch in der Spezifikation nicht erforderlich. Möglicherweise verwenden sie eine zusätzliche Indirektionsebene, um die Garbage Collection zu vereinfachen. Am Ende kommt es jedoch (fast immer) darauf an, dass (C-artige) Zeiger an der Implementierung von (Java-artigen) Referenzen beteiligt sind.
Sie können mit Referenzen keine Zeigerarithmetik ausführen. Der wichtigste Unterschied zwischen einem Zeiger in C und einer Referenz in Java besteht darin, dass Sie den zugrunde liegenden Wert einer Referenz in Java tatsächlich nicht ermitteln (und bearbeiten) können. Mit anderen Worten: Sie können keine Zeigerarithmetik ausführen.
In C können Sie einem Zeiger (dh der Adresse) etwas hinzufügen oder etwas subtrahieren, um auf "nahe" liegende Objekte oder Orte zu verweisen, die sich an einem beliebigen Ort befinden.
In Java verweist ein Verweis auf eine Sache und nur auf diese Sache. Sie können festlegen, dass eine Variable einen anderen Verweis enthält, aber Sie können sie nicht einfach bitten, auf "das Objekt nach dem ursprünglichen Objekt" zu verweisen.
Referenzen sind stark typisiert. Ein weiterer Unterschied besteht darin, dass der Typ einer Referenz in Java viel strenger gesteuert wird als der Typ eines Zeigers in C. In C können Sie ein haben
int*
und es in einchar*
umwandeln und den Speicher an dieser Stelle einfach neu interpretieren. Diese Neuinterpretation funktioniert in Java nicht: Sie können das Objekt am anderen Ende der Referenz nur als etwas interpretieren, das es bereits ist (dh Sie können eine Referenz nur dann auf eineObject
ReferenzString
umwandeln , wenn das Objekt, auf das verwiesen wird, tatsächlich eine istString
).Diese Unterschiede machen C-Zeiger leistungsfähiger, aber auch gefährlicher. Beide Möglichkeiten (Zeigerarithmetik und Neuinterpretation der Werte, auf die verwiesen wird) verleihen C Flexibilität und sind die Quelle für einen Teil der Macht der Sprache. Sie sind jedoch auch eine große Problemquelle, da sie bei falscher Verwendung leicht die Annahme aufheben können, dass Ihr Code darauf aufgebaut ist. Und es ist ziemlich einfach, sie falsch zu benutzen.
quelle
memcpy
Verschieben eines Zeigers nach achar[]
) und umgekehrt. Wenn ein Zeiger in eine Folge von Zahlen konvertiert wird, die irgendwo gespeichert ist (möglicherweise auf dem Bildschirm angezeigt und vom Bediener auf einen Zettel kopiert), werden alle Kopien des Zeigers im Computer zerstört und diese Folge von Zahlen konvertiert Zurück zu einem Zeiger (möglicherweise nachdem er vom Bediener eingegeben wurde), muss der Zeiger immer noch auf dasselbe zeigen, was er zuvor getan hat. Ein Programm, das ...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 neu gesetzt 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 kein Verweis auf einen Verweis
quelle
Java-Referenzen und C-Zeiger unterscheiden sich in genau zwei Punkten:
char
,int
und so weiter).Jemand hat geschrieben, dass Verweise stark typisiert sind, weil Sie den Compiler nicht zwingen können, ein
int*
als ein zu behandelnchar*
.Ganz abgesehen von der Tatsache, dass diese bestimmte Umwandlung tatsächlich sicher ist , gibt es in C keinen Polymorphismus, so dass der Vergleich kein Starter ist.
Sicher ist Java stärker typisiert als C, nicht dass dies ein Merkmal von C-Zeigern gegenüber Java-Referenzen ist. Sie müssen die JNI verwenden, um die Typensicherheit aufzuheben (abgesehen von der Nichtbeachtung generischer Einschränkungen), aber selbst in C müssen Sie sie erzwingen der Compiler.
Jemand schrieb, dass Java-Referenzen als C-Zeiger implementiert werden könnten, auf denen ich sicher bin, dass sie auf 32-Bit-Computern, die in C implementiert sind, normalerweise weniger leistungsfähig sind . Auf 64-Bit- Rechnern handelt es sich normalerweise um komprimierte gewöhnliche Objektzeiger ("Compressed OOPs"), um Speicherplatz und Bandbreite zu sparen.
Auf jeden Fall müssen diese C-Zeiger auch nicht den Hardware-Adressen entsprechen, selbst wenn sie normalerweise (> 99% der Implementierungen) aus Leistungsgründen vorliegen.
Schließlich ist dies ein Implementierungsdetail, das dem Programmierer nicht bekannt ist.
quelle
Sie sind etwas anders. In Java wird eine Kopie der Referenz in den Stapel einer aufgerufenen Funktion kopiert, wobei auf dasselbe Objekt wie die aufrufende Funktion verwiesen wird und Sie dieses Objekt bearbeiten können. Sie können jedoch nicht das Objekt ändern, auf das sich die aufrufende Funktion bezieht.
Betrachten Sie den folgenden Java-Code
Betrachten Sie nun einen Zeiger in c ++:
quelle