Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo!
Ich bin zurzeit "Programmiersprachen-hungrig" =)
Soll heißen: Ich habe HTML, CSS, C, C++, Delphi bereits gelernt (C und C++ nicht perfekt, ich weiß was Zeiger sind, kann Dateien auslesen und so aber mehr auch nich )
Nun möchte ich die mächtige Sprache "Java" erlernen. Bevor ich anfange diese zu erlernen möchte ich eine grundlegende Frage wissen, die ich im Netz einfach nicht finden konnte.
Es wird überall geschrieben das Java für Websites und Softwarekomponente benutzt wird, DOCH nirgends steht wofür man es genau einsetzen kann.
1.) Kann man damit z.b. ein Upload-Programm für Websites machen?
2.) Kann man vielleicht Spiele programmieren? Wenn ja 3D Spiele oder nur "Flash Games" ? (ich weiß mit c++ ist fürs Spieleprogrammieren die meistgebrauchte Sprache...is ja nur ne theorethische frage ^^)
3.) Könnte man z.b. Programme wie "Adobe Photoshop" (ich weiß sehr sehr viel Arbeit steckt dahinter...is ja nur theorethische frage ^^) oder ein Sicherheitsprogramm wie "norton antivirus" (ich weiß...fast unmöglich aber wie gesagt...sind nur theoretische Fragen)
Wenn ihr mir dies beantworten könntet wäre ich heilfroh!
2.) Kann man vielleicht Spiele programmieren? Wenn ja 3D Spiele oder nur "Flash Games" ? (ich weiß mit c++ ist fürs Spieleprogrammieren die meistgebrauchte Sprache...is ja nur ne theorethische frage ^^)
So theoretisch ist die garnicht: http://www.bytonic.de/html/jake2.html
3.) Könnte man z.b. Programme wie "Adobe Photoshop" (ich weiß sehr sehr viel Arbeit steckt dahinter...is ja nur theorethische frage ^^) oder ein Sicherheitsprogramm wie "norton antivirus" (ich weiß...fast unmöglich aber wie gesagt...sind nur theoretische Fragen)
Ersteres schon, letzteres eher weniger - ein Antivirenprogramm braucht (vermutlich immer) HÖCHST spezifische Kenntnisse über das Betriebssystem - und genau die Notwendigkeit, diese Kenntnisse zu haben, will man mit einer Plattforumunabhängigen Sprache ja vermeiden.
Zu 1: Meinst du sowas FTP-Mäßiges? Java bietet von Natur aus viele "einfache" Möglichkeiten für "alles, was mit Netzwerken zu tun hat", aber bei einem Upload hat der Server ja noch ein Wörtchen mitzureden... (kenn mich' da nicht so aus)
Zu 1.) Ich kenn mich da auch nich so aus aber einfach so ein Button auf z.b. ner homepage und da sucht man sich dann die datei vom rechner aus und loadet die hoch. sowas dürfte schon gehen oder?
danke für die anderen antworten! dann fang ich halt mal an mit java =)..hab gelesen da gibts keine pointer(zeiger)--> JUHU!!!
ALLES sind Zeiger (außer den primitiven Datentypen). Aber man kann nicht den gleichen Mist damit machen, wie in C/C++, und alles, was daran "kompliziert" ist, ist "versteckt".
Zu 1.) Ich kenn mich da auch nich so aus aber einfach so ein Button auf z.b. ner homepage und da sucht man sich dann die datei vom rechner aus und loadet die hoch. sowas dürfte schon gehen oder?
NICHTS sind in Java Zeiger. Es gibt nur Referenzen aber nicht das, was man als "Pointer" versteht.
Du arbeitest in Java also tatsächlich nur mit Objekten, und schiebst nicht irgendwelche Zeiger hin und her
Auch auf die Gefrahr hin, dass (mal wieder) ein Thread in eine philosophische Detaildiskussion abschweift: Eine Java-Referenz auf ein Objekt ist praktisch das gleiche wie ein C++-Pointer: Belegt ca. 4 bytes, kann null sein, oder auf einen "Speicherbereich" zeigen, wird by value an methoden übergeben... Dass man den nicht durch zeiger+=4 woanders hinschieben kann usw. hatte ich ja angedeutet. Zumindest eins ist sicher: Der Unterschied zwischen einer C++-Referenz und einer Java-Referenz ist größer als der Unterschied zwischen einem C++-Pointer und einer Java-Referenz
Eigentlich sind Referenzen genau das, Zeiger ohne Arithmetik.
War wohl eine Marketing Entscheidung sie Referenzen zu nennen, wobei man dann konsequenterweise auch gleich eine NullReferenceException anstatt einer NullPointerException hätte haben sollen.
NICHTS sind in Java Zeiger. Es gibt nur Referenzen aber nicht das, was man als "Pointer" versteht.
Du arbeitest in Java also tatsächlich nur mit Objekten, und schiebst nicht irgendwelche Zeiger hin und her
Blödsinn, Pointer sind ebenso Referenzen, wie "Referenzen in Java". Du arbeitest in Java nicht mit Objekten, sondern mit Referenzen auf deine Objekte.
Wahrscheinlich "verstehst" du nur was falsches unter "Pointer".
In diesem Kontext klingt es eher so, als wärst du kein pointer-müder programmierer, der nach 10 Jahren Suche nach nirvana-zeigern die Schnauze voll hat, und sich deshalb auf Java freut, sondern viel mehr jemand, der nicht mal am Anfang Spaß an der Sache gefunden hat, d.h. überhaupt nie richtig gerafft hat, wozu die Zeiger da sind. :roll:
Und überhaupt, wenn deiner Meinung nach die Zeiger alles sind, was C++ ausmacht, dann hast du dich da wohl nicht allzu genau eingelesen: den Mist mit den Zeigern gibt's in C auch schon...
Also, ich find die Aussage einfach so merkwürdig... Als ich von C/C++ auf Java umgestiegen bin, da fühlte ich mich zwei Wochen lang erstmal so, als hätte man mir 9 Finger amputiert, nur wegen den fehlenden Zeigern :roll: deswegen find' ich die Reaktion etwas seltsam^^ ???:L
Das allerdings ist falsch. Java selber arbeitet mit den Referenzen, aber du nicht.
Wenn du den Namen eines Objekts hinschreibst, ist nämlich immer das Objekt by value gemeint, und keinesfalls
irgendeine Referenz/Pointer/nenn es wie du willst. Du arbeitest schlichtweg nicht mit Referenzen, das gibt's nicht.
Du arbeitest mit Objekten.
Du kannst mir kein Code-Beispiel geben, wo du mit einer Referenz arbeitest.
Das allerdings ist falsch. Java selber arbeitet mit den Referenzen, aber du nicht.
Wenn du den Namen eines Objekts hinschreibst, ist nämlich immer das Objekt by value gemeint, und keinesfalls
irgendeine Referenz/Pointer/nenn es wie du willst. Du arbeitest schlichtweg nicht mit Referenzen, das gibt's nicht.
Du arbeitest mit Objekten.
Du kannst mir kein Code-Beispiel geben, wo du mit einer Referenz arbeitest.
public f(Object[] objects){
for(Object o: objects){
System.out.println(o.hashCode());
}
}
"objects" ist da sicherlich nich "by value" übergeben, das sind definitiv alles referenzen. Es werden überall nur 4byte-lange referenzen hin und her geschoben, die jvm gibt sich sicherlich keine mühe, nur für so einen dämlichen funktionsaufruf das ganze array zu kopieren und by value in diese methode rüberzutransportieren, das wäre ein viel zu gigantischer aufwand, der eh fast nie nötig ist...
Okay, man könnte vielleicht sagen, dass durch "." alles sofort dereferenziert wird, und man "das eigentliche Objekt" vor sich hat... Aber kA, das ist doch jetzt alles Wortverdreherei, solang man weiß was es tut ist doch alles okay...
und damit arbeitest du auf dem Objekt o. Nochmal: Klar hat Java Referenzen, aber du als Programmierer
hast darauf keinen Zugriff. Du bennenst Objekte nach ihrem Namen, nicht nach ihrer Referenz.
Und du kannst nur die values von Objekten ändern, nicht irgendwelche Referenzen.
Komm schon, ihr wisst doch was ich meine?! Ich finde den Satz "arbeiten mit Referenzen" einfach
falsch in Java. Du kannst mit Referenzen nicht arbeiten, wie gesagt nicht mal was du in der Methode
übergibst ist für dich eine Referenz. Es ist auch nur ein Objekt (ein Array). Es ist halt NICHT ein 4-byte
Pointer, wie du es sagst. Das macht die JVM dann daraus, aber es ist das Objekt by value, das du dorthin
schreibst. Du kannst keine Referenz schreiben
edit: Um es vllt deutlicher zu machen: Wir programmieren in Java, so heisst die Sprache.
Das ist nicht die JVM! Und in der Sprache java gibt es keine Referenzen.
Doch, jede Variable die du erstellst ist eine Referenz auf ein Objekt (gut, primitive sind wieder was anderes).
Das einzige was in Java nicht vorhanden ist, ist die aus C geliebte Pointerarithmetik wie die * und & Operatoren. Vielleicht bist du deswegen so verwirrt.
Ich weiß wie es da innendrin funktioniert und was mein code bewirkt. Wie du es nennst oder beschreibst ist mir daher vollkommen egal. Ich bin davon überzeugt, dass du das richtige meinst, nur imho sollte man aufhören zu versuchen das richtige zu sagen, und stattdessen einfach nur das richtige denken.
Das ist wie in diesen Informatik-vorlesungen: der Prof steht da rum und erzählt zwei stunden lang irgendwas von "by value" und "by pointer" und "by reference", und die leute die das vorher nicht gerafft haben, wissen nachher genauso wenig, und sitzen da mit dem :bahnhof: Gesichtsausdruck.
Es ist doch ganz einfach: man lese sich die einzeiligen definitionen zu pointern und referenzen und zeigern durch, dann nehme man einen C-Compiler, und falle solange auf die Fresse, bis man es kapiert hat. Nach zwei Stunden ist das schwer ausformulierbare Wissen ohne den unnötigen Weg über das Sprachzentrum direkt in den Rückenmark rüberdiffundiert, und wird auch nicht mehr vergessen.
Ich finde den Satz "arbeiten mit Referenzen" einfach falsch in Java.
Alles bis auf Primitive Datentypen wird in Java über Refernzen verwaltet und übergeben. Und ich meine, damit schonmal gearbeitet zu haben. Mir kommt deshalb der Ausdruck "arbeiten mit Referenzen" nicht falsch vor, kA was dich da so dran stört.
Mir ist auch klar dass jeder hier das gleiche meint, aber es ist auch wichtig dass sich Leute richtig
ausdrücken können, und nicht nur das richtige denken. Wenn das so wär, hätten wir ein Problem...
Ich starte noch einen Überzeugungsversuch:
Call-By-Reference ist ein englischer Ausdruck und bedeutet frei übersetzt "anwählen über einen Zeiger".
In C++ geht das: Ein dreizeiler schafft dir einen Buffer Overflow, und schon kannst du Inhalte
aus dem Speicher in dein Programm einbauen, die dort eigentlich nirgends definiert sind.
Du hast soeben etwas über eine Referenz im Speicher angewählt, Glückwunsch.
In Java g e h t d a s n i c h t.
Du kannst nichts ansprechen, dass du dir nicht vorher als Objekt erstellt und benannt hast.
Alles, was du irgendwo im Src reinschreibst, bennent einen Namen, den du vorher definiert hast.
Dieser Name steht für ein Objekt mit gewissen Inhalten, und nicht für einen Zeiger auf eine Stelle im Speicher.
Es ist Call-By-Value.
Ich sag nochmal: Java ist eine Programmiersprache. Damit meint man das, was wir sehen. Man meint damit
nicht die Arbeit mit dem Hauptspeicher. Denn hier ist jedes Programm gleich: Alle 53148 Programmiersprachen
dieser Welt sind das selbe, und zwar Maschinencode die mit dem Speicher reden.
Aber das meint man nicht, wenn man von einer Sprache redet. Eine Sprache ist nach Definition eine Sammlung
von Wörtern und Grammatik. Referenzen gehören nicht zur Sprache Java, es gibt dieses Wort nicht und keine
Grammatik, die damit etwas tun kann.
EDIT: Achso wenn ich hier Referenzen sage, meine ich Pointer in c++!!
Also... ich find's falsch, einfach falsch. Mir egal was du denkst, wenn du mir sagst in JAva arbeitest du mit
Referenzen, dann denk ich mir "Ja du denkst das richtige, aber du hast gerade das falsche gesagt" :bae:
Und zwar ist der Satz genau an der Stelle falsch geworden, wo du "Java" gesagt hast. Denn das ist eine Sprache.
Mir ist auch klar dass jeder hier das gleiche meint, aber es ist auch wichtig dass sich Leute richtig
ausdrücken können, und nicht nur das richtige denken. Wenn das so wär, hätten wir ein Problem...
nein, du denkst das falsche. Warum, steht weiter unten.
Ich starte noch einen Überzeugungsversuch:
Call-By-Reference ist ein englischer Ausdruck und bedeutet frei übersetzt "anwählen über einen Zeiger".
In C++ geht das: Ein dreizeiler schafft dir einen Buffer Overflow, und schon kannst du Inhalte
aus dem Speicher in dein Programm einbauen, die dort eigentlich nirgends definiert sind.
Du hast soeben etwas über eine Referenz im Speicher angewählt, Glückwunsch.
In Java g e h t d a s n i c h t.
Du kannst nichts ansprechen, dass du dir nicht vorher als Objekt erstellt und benannt hast.
Alles, was du irgendwo im Src reinschreibst, bennent einen Namen, den du vorher definiert hast.
Dieser Name steht für ein Objekt mit gewissen Inhalten, und nicht für einen Zeiger auf eine Stelle im Speicher.
Es ist Call-By-Value.
Hey, du hast wohl geantwortet bevor ich eine Sache editiert hatte:
Aber das meint man nicht, wenn man von einer Sprache redet. Eine Sprache ist nach Definition eine Sammlung
von Wörtern und Grammatik. Referenzen gehören nicht zur Sprache Java, es gibt dieses Wort nicht und keine
Grammatik, die damit etwas tun kann. EDIT: Achso wenn ich hier Referenzen sage, meine ich Pointer in c++!!
..und jetzt sind wir uns einig, oder?
Es gibt in Java kein Wort, dass einen Pointer in C++ beschreibt
edit: Moment mal, ihr setzt ja C++ Pointer eben immer gleich mit Java Referenzen...
Hmm boah das wird anstrengend Naja ich les mir mal deine Links durch und zieh bis dahin
den Kopf ein. Wenn alle etwas anderes darunter verstehen als ich, bin wohl eher ich im Unrecht.
Für mich hört sich das so an, als ob Java tatsächlich Call-By-Reference arbeitet.
Und dass das nicht stimmt, da sind wir uns ja alle einig.
Also ich komm grad echt total durcheinander :/ Was ist für die der Unterschied zwischen einer Referenz
und einem Pointer? Und was meinen sie mit "reference values", der Wert wofür?
Okay, es sind Pointer ich kann ja machen
obj = a;
obj = b; // obj zeigt jetzt auf b
Aber wieso funktioniert das dann nicht bei der Übergabe in Methoden? Was wird DORT übergeben?
public void (Object obj) //<- was ist dann der Parameter? Referenz? Pointer? Wert? Hä?
Ist jmd so gnädig mich zu bekehren Ich meine ich weiss wie es funktioniert, aber ich hab
da grad echt ein Begriffs-Wirrwarr in meinem Kopf. Für mich ist Pointer etwas, was ich mit C# in der uni
gelernt habe, und das es in Java nicht gibt.
Ich sag nochmal: Java ist eine Programmiersprache. Damit meint man das, was wir sehen. Man meint damit
nicht die Arbeit mit dem Hauptspeicher. Denn hier ist jedes Programm gleich: Alle 53148 Programmiersprachen
dieser Welt sind das selbe, und zwar Maschinencode die mit dem Speicher reden.
Aber das meint man nicht, wenn man von einer Sprache redet. Eine Sprache ist nach Definition eine Sammlung
von Wörtern und Grammatik.
Was soll dieses Blah jetzt?
In C++ gibt es einen sehr scharfen und klaren Unterschied zwischen call-by-value und call-by-reference.
Im ersten Fall wird auf dem Argument ein Copy-Konstruktor aufgerufen, und das ursprünglich übergebene Objekt bleibt von den manipulationen in der Methode auf jeden Fall unangetastet.
Im zweiten Fall wird die referenz auf das objekt übergeben, und alle änderungen in der methode sind auch draußen sichtbar.
Das sind zwei vollkommen verschiedene paar schuhe. Diese Sachen werden unterschiedlich geschrieben. Diese Sachen werden unterschiedlich ausgeführt. Da kannst du nicht mit irgendwelchen Sprüchen kommen, dass die Sprachsyntax an sich irgendwie von den Prozessen innendrin erstmal unabhängig wäre. In Java wird klar die zweite Möglichkeit verwendet. Wenn du mit den Werten des übergebenen Objektes arbeiten, aber das eigentliche Objekt "draußen" unangetastet lassen willst, hast du keine andere wahl, als innen in der Methode erstmal clone() aufzurufen, und dann erst mit diesem geklonten Objekt weiterzuarbeiten. Erst diese etwas umständliche Konstruktion würde dem C++ call-by-value in etwa entsprechen. In C++ hat der her Stoustrup den leuten diese paar Zeilen eben erspart...
Ist jmd so gnädig mich zu bekehren Ich meine ich weiss wie es funktioniert, aber ich hab
da grad echt ein Begriffs-Wirrwarr in meinem Kopf. Für mich ist Pointer etwas, was ich mit C# in der uni
gelernt habe, und das es in Java nicht gibt.
call-by-value: methode kriegt eine komplette Kopie des übergebenen objektes, mit allen Gedärmen und member-variablen. Wird innen in der methode irgendwas an dieser Kopie geändert, so kriegt das Objekt draußen nichts von diesen veränderungen mit. In C++ wird das mit Copy-Konstruktoren umgesetzt. In Java gibt's das nur für primitive datentypen.
call-by-pointer: methode kriegt die Speicheradresse des Objektes. Alle veränderungen, die innen vorgenommen verden, werden direkt am übergebenen objekt vorgenommen, die methode greift ja direkt auf den speicher des Objektes zu. D.h. das übergebene Objekt "draußen" spürt alle Veränderungen, die an seinem Inhalt innerhalb der methode vorgenommen werden. In Java ist es "im prinzip so" nur dass man an die speicheradressen nicht willkürlich +1143 draufaddieren darf. In C++ ist das direkt möglich, da kriegt man wirklich die speicheradresse als "Zahl" übergeben.
call-by-reference: Tut praktisch dasselbe wie call-by-pointer. In C++ ist es so eine Art "verschleierte" call-by-pointer übergabe. Da wird genauso eine Speicheradresse des Objektes übergeben, allerdings sieht das rein Optisch einer call-by-value übergabe ähnlicher, d.h. man kann sich einen haufen nerviger "*"-Sternchen und "->"-Pfeilchen sparen. Aber man fummelt immer noch direkt am inhalt des "draußen" vorhandenen Objektes herum. In Java ist das alles immer "verschleiert", man kann da niemals +3243 auf einen zeiger draufaddieren, deswegen heißt es "call-by-reference" was ja auch sehr schön mit C++ zusammenpasst.
So... Hab ich das jetzt alles richtig und verständlich dargestellt? ???:L
Nichts für ungut hdi, aber was Du hier in diesem Thread schreibst, ist absoluter Blödsinn. Vielleicht informierst Du Dich erstmal, bevor Du falsche Behauptungen aufstellst?
Natürlich gibt es in Java Referenzen und diese sind nichts anderes als Pointer (jedoch ohne Pointer Arithmetik). Es gehört zu den elementarsten Java-Grundlagen zu verstehen, wie Referenzen in Java funktionieren.
Foo obj = new Foobar(); <<< obj ist eine Referenz
Das, was man im allgemeinen unter Call By Reference versteht, gibt es in Java allerdings nicht, weil bei einem Methodenaufruf nicht die eigentliche Referenz übergebe wird sondern der "Reference-Value", also eine Kopie der Referenz.
doSomething(obj); <<< Referenz obj wird als Kopie übergeben (quasi ein Call by Reference-Value)
Damit werden solch unschöne Seiteneffekte verhindert, dass man ausserhalb des Scopes Zeiger (also Referenzen) umbiegen kann.
Hab mit bestem Wissen und Gewissen gepostet. Ich dachte, ich bin informiert...
...Ich hab irgendwann mal erfahren, es gäbe kein Call-By-Reference (siehe FAQ). Das der Effekt so ähnlich ist,
war mir durchaus klar. Ich dachte nur, da es kein Call-By-Reference gibt, gibt es auch keine Referenzen.
Ich meine dass es die intern gibt war mir schon immer klar, aber ich hielt den Begriff in Zusammenhang mit
Java nicht korrekt (deswegen vorhin mein "Blah" zur Sprache)
doSomething(obj); <<< Referenz obj wird als Kopie übergeben
Call-by-Value auf einer Referenz, man kann also nur die Referenz nicht austauschen, weil es nur eine Kopie ist.
Sei zeigt aber wie das Original auf ein bestimmtes Objekt, und alle Änderungen wirken sich auch langfristig
auf das Objekt aus.
Okay, ich dachte bisher man übergibt nur Objekte, also Sammlungen von Werten, und man kann die Werte ändern,
aber nicht die "Sammlung" an sich. Und so ist es ja auch, nur halt die Begriffe waren mir nicht klar.
In diesem Kontext klingt es eher so, als wärst du kein pointer-müder programmierer, der nach 10 Jahren Suche nach nirvana-zeigern die Schnauze voll hat, und sich deshalb auf Java freut, sondern viel mehr jemand, der nicht mal am Anfang Spaß an der Sache gefunden hat, d.h. überhaupt nie richtig gerafft hat, wozu die Zeiger da sind. :roll:
Und überhaupt, wenn deiner Meinung nach die Zeiger alles sind, was C++ ausmacht, dann hast du dich da wohl nicht allzu genau eingelesen: den Mist mit den Zeigern gibt's in C auch schon...
Also, ich find die Aussage einfach so merkwürdig... Als ich von C/C++ auf Java umgestiegen bin, da fühlte ich mich zwei Wochen lang erstmal so, als hätte man mir 9 Finger amputiert, nur wegen den fehlenden Zeigern :roll: deswegen find' ich die Reaktion etwas seltsam^^ ???:L
ich hab mit C angefangen und mit C++ mal reingeschnüffelt...ich meine ich bin erst junge 15 jahre...ich will nur ma wissen was ich zuerst angehe und sou ^^
kann ja in C und C++ nur bis Zeiger (einschließlich pointer)..sind zwar wichtige dinge aber einfach zum kotzn...die mag ich einfach nich..kA warum...
is halt meine meinung ^^...und in java gibt es keine pointer..in java nennt man sie referenzen (sind pointer-ähnlich) aber sie heißen halt referenzen....habs auf ca. 6 seiten nachgelesen ^^
ich hab mit C angefangen und mit C++ mal reingeschnüffelt...ich meine ich bin erst junge 15 jahre...ich will nur ma wissen was ich zuerst angehe und sou ^^
Vielleicht kann ich ja hdis Verwirrung noch ein Stückchen mehr entwirren:
Bei dem Ganzen by-value und by-reference Gerede gibt es theoretisch 2 Sachen, die gemeint sein könnten. (Also, ich rede von Objekten, nicht von Primitiven - dass die by-value übergeben werden ist ja klar):
Das eine ist sozusagen die eigentliche Variable. Die enthält nämlich im Endeffekt nur die Speicheradresse des Objektes, um das es geht. Davon kriegt man nur in Java exakt gar nichts mit.
Das andere ist das eigentliche Objekt, und darüber zu reden macht mehr Sinn. Die Sache ist jetzt allerdings die: Die "Speicheradresse" wird, genau wie ein primitiver Wert by-value übergeben. Das sieht man so:
Code:
public void foo(Object o) {
o = something.else(); // In der aufrufenden Methode ändert sich nichts an der Variable
}
Viel interessanter ist aber, dass dadurch das eigentliche Objet "by-reference" übergeben wird:
Code:
public void bar(Changeable o) {
o.change(); // Auch in der aufrufenden Methode wird o verändert!
}
In C# gibt es, nebenbei bemerkt, auch so etwas:
Code:
public void Foo(ref object o) { // in C# ist übrigens auch int etc. von object abgeleitet
o = something.Else(); // Auch in der aufrufenden Methode ändert sich die Variable!
}
Ahh, da ist sie ja, die Diskussion. Auf manche Dinge kann man sich eben verlassen.
Nur so als Einwurf: Ich glaube, dass ein Großteil der Verwirrung und Worklauberei daher kommt, dass die Begriffe "Pointer" und "Referenz" für sich genommen nicht eindeutig sind. Man muss schon immer sagen, welche Sprache man meint. In C++ ist eine Referenz etwas GANZ anderes als in Java. (Dafür gibt's in C++ Referenzen auf Pointer )
public void Foo(ref object o) { // in C# ist übrigens auch int etc. von object abgeleitet
o = something.Else(); // Auch in der aufrufenden Methode ändert sich die Variable!
}
und "Type** ppZeigerszeiger" gab's wofür? ???:L Die syntax war zumindest konsistent und verständlich... Weiß jetzt nicht inwiefern "ref type name" eine verbesserung davon sein soll... :roll: aber gut, kA von C# da braucht ihr mich jetzt nicht davon zu überzeugen wie toll es mit "ref Type name" ist...
In C++ ist eine Referenz etwas GANZ anderes als in Java
Du meinst jetzt also die "nicht-C++-pointer-sondern-c++-referenz" und die "stinknormal-java-referenz"?
okay... hdi ist jetzt glaub ich mal fertig, aber was ist jetzt an einer C++ referenz so viel anders als in java-referenz? jetzt fängt bei mir der bahnhof-zustand an :shock:
edit: äääh, ne, alles richtig, mich hat jetzt nur deine formulierung kurzfristig voll verwirrt. was ich vorhin geschrieben hab trifft auch nicht so wirklich zu, auch wenn sich referenzen in c++ bei argumenten ähnlich verhalten, wie die java-referenzen.
Aber welchem c++ ding würden die java-referenzen also entsprechen? ???:L Die sehen doch in etwa aus wie c++ referenzen, aber verhalten sich eigentlich fast genauso wie c++ zeiger... Wieso nennst du die referenzen auf zeiger? :bahnhof:
oh ne leute, ehrlichgesagt: ich will's gar nich wissen, sonst wach ich in ~6 stunden auf und weiß nicht mehr was in java 'ne referenz ist :autsch: Das ist alles nur total verwirrend.
Du meinst jetzt also die "nicht-C++-pointer-sondern-c++-referenz" und die "stinknormal-java-referenz"?
okay... hdi ist jetzt glaub ich mal fertig, aber was ist jetzt an einer C++ referenz so viel anders als in java-referenz? jetzt fängt bei mir der bahnhof-zustand an :shock:
edit: äääh, ne, alles richtig, mich hat jetzt nur deine formulierung kurzfristig voll verwirrt. was ich vorhin geschrieben hab trifft auch nicht so wirklich zu, auch wenn sich referenzen in c++ bei argumenten ähnlich verhalten, wie die java-referenzen.
Aber welchem c++ ding würden die java-referenzen also entsprechen? ???:L Die sehen doch in etwa aus wie c++ referenzen, aber verhalten sich eigentlich fast genauso wie c++ zeiger... Wieso nennst du die referenzen auf zeiger? :bahnhof:
oh ne leute, ehrlichgesagt: ich will's gar nich wissen, sonst wach ich in ~6 stunden auf und weiß nicht mehr was in java 'ne referenz ist :autsch: Das ist alles nur total verwirrend.
OK, ich antworte trotzdem - vielleicht schaff' ich es ja, Aussagen zu machen, die einfach UND präzise sind...:
Ein C++-Pointer ist eine Variable, die als Wert einen Speicherbereich enthält. Ein C++-Pointer enthält als Wert also den Speicherbereich, an dem das Objekt steht, auf das - bildlich gesprochen - der C++-Pointer zeigt.
Code:
// Eine (nicht funktionierende!) Swap-Funktion für C++-Pointer:
// Die Pointer werden BY VALUE an diese Funktion übergeben
void swap(Foo *x, Foo *y)
{
Foo *temp = x;
x = y;
y = temp;
}
Foo *a = new Foo(1); // a ist ein Zeiger auf die Stelle, an der das neue Foo(1) liegt
Foo *b = new Foo(2); // b ist ein Zeiger auf die Stelle, an der das neue Foo(2) liegt
// Ein swap, das nicht funktioniert:
swap(a,b);
print(a->value); // Gibt immernoch "1" aus
print(b->value); // Gibt immernoch "2" aus
// Zuweisung
a = b; // a zeigt jetzt auch auf die Stelle, an der Foo(2) liegt (und man hat ein Memory leak :wink: )
print(a->value); // Gibt jetzt "2" aus
b = NULL;
print(b->value); // Kracht
Abgesehen von Zeigerarithmetik, **zeigerZeigern und anderen Zaubereien ist eine Java-Referenz genau das gleiche. Man kann sie auf verschiedene Objekte "zeigen" lassen, ohne dass die Objekte davon beeinflusst werden. Wenn man den Wert der Java-Referenz verändert, verändert sich das Objekt nicht. Java-Referenzen werden (wie die C++-Pointer oben) immer BY VALUE an Methoden übergeben. Der obige Code läßt sich also leicht nach Java übersetzen:
Code:
// Eine (nicht funktionierende!) Swap-Funktion für Java-Referenzen
// Die Referenzen werden BY VALUE an diese Funktion übergeben
void swap(Foo x, Foo y)
{
Foo temp = x;
x = y;
y = temp;
}
Foo a = new Foo(1); // a ist eine Java-Referenz das neue Foo(1)
Foo b = new Foo(2); // a ist eine Java-Referenz das neue Foo(2)
// Ein swap, das nicht funktioniert:
swap(a,b);
print(a.value); // Gibt immernoch "1" aus
print(b.value); // Gibt immernoch "2" aus
// Zuweisung
a = b; // a referenziert jetzt auch auf das Foo(2)
print(a.value); // Gibt jetzt "2" aus
b = null;
print(b.value); // Kracht
Langweilig - im eigentlichen Code wurde nichts geändert, außer dass alle "*" Sternchen weggenommen wurden, und die Dereferenzierungen von "a->value" zu "a.value" geändert wurden.
Das interessante ist, das der Code sich prinzipiell noch genauso verhält: Wie auch in der C++-Version ist die Ausgabe
1,2,2. Wie auch in der C++-Version funktioniert das "swap" nicht. Alles ist perfekt analog zur C++-Version mit C++-Pointern.
Im Vergleich dazu gibt's in C++ aber auch Referenzen. Die werden meistens für Argumente von Methoden verwendet (eben um "call by Reference" zu ermöglichen) aber manchmal auch als "Abkürzungen" für andere Objekte.
Code:
// Eine (funktionierende!) Swap-Funktion für C++-Pointer:
// Die Pointer werden BY REFERENCE an diese Funktion übergeben.
// Foo& *x ist eine Referenz auf einen Pointer
void swap(Foo& *x, Foo& *y)
{
Foo *temp = x;
x = y;
y = temp;
}
Foo *a = new Foo(1); // a ist ein Zeiger auf die Stelle, an der das neue Foo(1) liegt
Foo *b = new Foo(2); // b ist ein Zeiger auf die Stelle, an der das neue Foo(2) liegt
// Ein swap, das funktioniert:
swap(a,b);
print(a->value); // Gibt "2" aus
print(b->value); // Gibt "1" aus
Eine C++-Referenz ist also etwas (ganz) anderes als ein C++-Pointer oder eine Java-Referenz:
C++-Pointer und Java-Referenzen sind praktisch "Variablen, die als Wert eine Beschreibung haben, an welcher Stelle ein Objekt liegt". Man kann mit Hilfe dieser Variablen leicht auf den Speicherbereich zugreifen, an dem die Objekte liegen. Und man kann sie auf andere Stellen zeigen/referenzieren lassen.
Eine C++-Referenz ist (sozusagen) KEINE Variable, sondern nur ein NAME. Lokal braucht eine C++-Referenz eigentlich keine "physische Repräsentation" zu haben. Da ist sie nicht viel mehr als eine "Abkürzung" - ein "Alias" für irgendwas anderes. Praktisch z.B. bei sowas wie
Code:
vector<Foo> fooVector;
...
Foo& b = fooVector[123]; // "Abkürzung"
b.value = 666;
...
print(fooVector[123].value); // Gibt 666 aus
Hoffentlich habe ich damit nicht mehr Ungenauigkeiten in den Thread eingebracht, also vorher schon da waren. Hm.
Ich hätte da einen gravierenden Unterschied: Java-Objekte haben im Gegensatz zu C++-Objekten einen Overhead. Während in C++ eine Referenz auf ein Objekt meistens auch gleich die Referenz auf den 1. Member dieses Objekts (vgl. Array) ist, hat man in Java eben nur eine Referenz auf das Objekt. In Java gibt es deswegen z.B. auch kein "sizeof", weil z.B. ein Obkekt des Typs String mit 11 Zeichen, anders als in C++, definitiv länger als 11 Bytes ist.
Hmm... Das kann eigentlich nicht stimmen. Nicht dass ich das wüsste... Aber wie würden denn virtuelle Methodenaufrufe in C++ realisiert, wenn es exakt keine Zusatzinformation am Objekt gäbe?
Das stimmt aber... Letztendlich muss man sich vor Augen führen, was aus C++ Quelltext nach dem kompilieren wird. Ich habe oben nicht ohne Sinn von Membern allgemein gesprochen. Diese Member können durchaus auch Methoden sein. Methoden in C++ sind durchweg Pointer auf ausführbaren Assembler-Code (Function-Pointer). Methoden-Parameter werden entweder auf den Stack gelegt oder in Register geschrieben.
So ein Unsinn. Referenzen auf Methoden können bei nicht-virtuellen Methoden direkte Sprünge sein. Virtuelle Methoden werden immer über eine VMT (oder ein vergleichbares Konstrukt) referenziert!
Spacerat hat gesagt.:
Methoden-Parameter werden entweder auf den Stack gelegt oder in Register geschrieben.
Doch. "Ohne Sinn" trifft's ganz gut. Du hast oben auch von String-Klassen gesprochen die seltsamer Weise genau ein Byte pro Zeichen benötigen. Nicht einmal nullterminiert sind sie. Und eine Längenangabe gibt's auch nicht. ???:L So what?
@Ebenius: Jetzt hast du mich aber da liegen LLLOOOOLLLL...
Von was für Zielsystemen reden wir hier? Haben deine verschiedenen Zielsysteme verschiedene Prozessoren? Dann hast du möglicherweise recht. Bei 68k-, PPC-, x64- und x86-Prozessoren ist es jedenfalls wie oben beschrieben.
Hab' ich villeicht den Fehler gemacht und das obige auf C++ spezifiziert? Dann verbesser' ich das mal. Jede Kompilersprache, deren Kompiler keinen speziellen Bytecode (wie z.B. Java) produzieren, produzieren Maschinen-Code. Und auf dieser Basis ist es völlig "Hupe", wie eine Funktion aufgerufen wird, es bleibt eine Sprungadresse. Und Parameterübergabe in Assembler funktioniert eben auch nur wie oben beschrieben (Stack oder Register).
Nachtrag: Nein "sizeof" gibts in Java immer noch nicht.
Auch in Java sind Methoden einfache Funktionspointer. Methoden werden vom Classloader initial geladen und in der Method Area abgelegt. Sie haben überhaupt nichts mit dem Objektzustand zu tun und beeinflussen natürlich auch nicht die Größe eines Objekts im Heap.
Klar... hab' auch nirgendwo geschrieben das der Kompiler das macht, lediglich das es letztendlich nur Sprungadressen sind (Aufrufbar mit "JMP" oder "JSR").
byto hat gesagt.:
Ist auch etwas schwierig in einer plattformunabhängigen Sprache, meinst Du nicht?
Auch in Java sind Methoden einfache Funktionspointer. Methoden werden vom Classloader initial geladen und in der Method Area abgelegt. Sie haben überhaupt nichts mit dem Objektzustand zu tun und beeinflussen natürlich auch nicht die Größe eines Objekts im Heap.
Natürlich landet man auch in Java irgendwann zwangsläufig auf der Assembler-Basis. Zwischen "Java" und "Assembler" liegt aber stets die JVM, in welcher die referenzierten Objekte eben den erwähnten "Overhead" haben.
Spacerat, lies Dir einfach mal Deine ersten beiden Posts auf der letzten Seite durch und dann versuch mal zu verstehen, was ich daran zu kritisieren hatte. Natürlich wird letztlich bei einem Methodenaufruf irgendwann mit irgendeinem Jump irgendwo hingesprungen. Was Du aber oben schreibst ist und bleibt falsch. In C++ haben Objekte Overhead. Sie müssen Overhead haben, um virtuelle Methoden abbilden zu können. Um nichts anderes ging es mir.
wenn du C, Assabler Objecte in Java aufrufst ensteht ein Overead, das ist richtig.
Das lieg aber nicht an der JVM, sonder an JNI. Da Java die Zeiger auf die C-Methoden kennen muss, müssen (weitere) wrapper her, diese erzeugen einen erheblichen Overhead. Bei echtzeitprogrammen (Spielen) macht sich das start in der Framerate bemerkbar.
Genaue werte hab ich nicht im Kopf, aber schafft ein C Programm 100fps kannst du über JNI ca. 20-30% bzw. frames abziehen (durch den JNI-overhead)
Solange du aber reine Java-Programme schreibt, das heisst; du lässt C völlig weg, entsteht kein overhead, da nur referenzen übergeben werden.
Die Referenz-Adresse lässt sich auch (super-)leicht mit System.out.println(object); ausgeben.
Mir ist es noch nie passiert, das dort Bytecode ausgegeben wird.
Fazit: Es sind referenzen.
Ich bleibe dabei und das ist keine Böswilligkeit: Diese Overheads haben C++-Objekte nur zur Kompile-Zeit. Nach dem Linken sind sie jedenfalls geschichte. In Java dagegen bleiben sie auch zur Laufzeit erhalten. Und genau darum ging es mir.
Ich bleibe dabei und das ist keine Böswilligkeit: Diese Overheads haben C++-Objekte nur zur Kompile-Zeit. Nach dem Linken sind sie jedenfalls geschichte. In Java dagegen bleiben sie auch zur Laufzeit erhalten. Und genau darum ging es mir.
Und genau dort verstehe ich's nicht. Auch von mir keine Böswilligkeit. Dann erklär mir bitte wie virtuelle Methodenaufrufe in C++ umgesetzt werden! Schon per Definition kann man dabei nicht zur Compile-Time binden. Warum gehst Du auf diese Frage nicht ein?