Schon gewusst?

Status
Nicht offen für weitere Antworten.
S

stev.glasow

Gast
Code:
Integer a = Integer.valueOf(88);
Integer b = Integer.valueOf(88);
System.out.println(a == b);
// Ausgabe: treu
valueOf(int) cachet die Instanzen der Werte -128 < x < 128 und liefert die jeweilige Instanz zurück. (Is bissel blöd erklärt.)

Kennt ihr noch mehr solche Schoten?
 
S

stev.glasow

Gast
Danke jdar:
Code:
String s0,s1 = s0 = "Bin neu hier.";
Hätte drauf schwören können, dass das nicht geht.
 
B

bygones

Gast
stevg hat gesagt.:
Code:
Integer a = Integer.valueOf(88);
Integer b = Integer.valueOf(88);
System.out.println(a == b);
// Ausgabe: treu
valueOf(int) cachet die Instanzen der Werte -128 < x < 128 und liefert die jeweilige Instanz zurück. (Is bissel blöd erklärt.)
Kennt ihr noch mehr solche Schoten?
willkommen in Java 5 :)

Sun bereut mittlerweilen in den Wrapper Klassen einen public Konstruktor reingehauen zu haben - man sollte immer (!) die valueOf Methode nutzen.

Noch eindeutiger ist es bei der Klasse Boolean. Man sollte nicht zigtausend mal new Boolean(true) schreiben, sondern Boolean.valueOf("true") bzw. Boolean.TRUE
 
S

stev.glasow

Gast
Achso, das gibt's erst ab der 1.5er. Das mit Boolean gab's ja schon vorher. Frag mich nur warum Integer.valueOf(String) das nicht so händelt.
 

0xdeadbeef

Top Contributor
@meez:
Hier werden Referenzen verglichen, die ja nur dann gleich sind, wenn sie tatsächlich auf das selbe Objekt verweisen. Per "valueOf" erzeugt man also keine neuen Instanzen, wenn ein Objekt gleichen Inhalts bereits existiert.´

@Stevg:
"treu" -> "true" würde das Verständnis evtl. vereinfachen...

IMHO war das aber mit Stringliteralen auch schon immer so.
 
S

stev.glasow

Gast
0xdeadbeef hat gesagt.:
IMHO war das aber mit Stringliteralen auch schon immer so.
Unverständlicher Weise nicht.
[edit] ne ich meinte Integer.valueOf(String) oder was meinst du jetzt?
 

Wildcard

Top Contributor
Ich finde das auch sehr seltsam. Das verhalten von Integer.valueOf und String hört sich für mich auf den ersten Blick gleich an.

Java ist auch eine Insel hat gesagt.:
für jedes Zeichenketten-Literal im Programm wird (bei Bedarf) automatisch ein entsprechendes String-Objekt erzeugt. Dies geschieht für jede konstante Zeichenkette höchstens einmal, egal wie oft sie im Programmverlauf benutzt wird.

Weiß jemand woran das liegt?
 

0xdeadbeef

Top Contributor
Ist halt ein schlauer Compiler, der die Ressourcen schont. Das ganze ist ja auch völlig ungefährlich, weil Strings und Wrapper-Objekte "immutable" sind.
 
B

Beni

Gast
Das liegt am Compiler, der da eifrig deinen Sourcecode optimiert :wink: (da ist glaub direkt in String ein Cach eingebaut?)
 
S

stev.glasow

Gast
Das ist nicht ganz das gleiche, das was in dem Zitat erwähnt wird läuft "intern" ab, denn new String("hallo") == "hallo" ergibt ja false, aber trotzdem wird nur eine Zeichenkette gespeichert. (Kein Plan wer das jetzt Regel, hatte eigentlich angenommen das dass die VM macht und nicht der Compilier.)
Und das mit Integer.valueOf(int) läuft nicht so, das wurde einfach mit Java so programmiert.
[edit]
oder so ähnlich :?
 

0xdeadbeef

Top Contributor
Das mit den Stringliteralen macht zumindest aller Wahrscheinlichkeit der Compiler. Wäre jedenfalls die sinnvollste und performanteste Lösung.
 

Wildcard

Top Contributor
Alles klar! bleibt aber noch eine Frage:
Warum haben SUN Klassen teilweise solche Rückgabewerte?
Code:
return new String()
Warum wird nicht auch hier String.valueOf() verwendet?
Mir drängt sich die Frage auf warum man für Integer, String, usw...überhaupt einen public Konstruktor zulässt und so unnöte Objekte vermeidet?
Gäbe es den nicht könnte man Strings auch problemlos mit '==' vergleichen und es würde im Anfängerbereich
ungefähr 1000 Threads zum Thema Stringvergleich weniger geben :wink:
 
S

stev.glasow

Gast
Die von Sun sind halt auch nur Menschen :) Und damit die Abwärtskompatibilität erhalten bleibt, läßt man die Public Konstruktoren drin. Bestimmt gibt es bei der Thematik auch noch einiges mehr zu beachten als dass was wir hier mit unseren Geistesblitzen erfasst haben. :wink:
 

thE_29

Top Contributor
Da stellt sich die Frage, wann brauche ich das ;)

Ich handhabe die Objekt Datentypen Klassen sowieso fast nie (also Integer, Long, Double) da ich immer mit den double, long, int arbeite weil ich das noch von C/C++ gewohnt war ;)

Am Anfang habe ich sogar meine eigenen Int -> String funktionen geschrieben, bis ich draufgekommen bin, dass es sowas schon gibt :D

Aber die Konstruktoren habe ich nie genutzt ..
 
S

stev.glasow

Gast
Wenn du z.B. nen int in einer Collection verwenden willst, könnte die Wrapper Klasse ganz praktisch sein :bae:
 
B

bygones

Gast
stevg hat gesagt.:
Wenn du z.B. nen int in einer Collection verwenden willst, könnte die Wrapper Klasse ganz praktisch sein :bae:
man kann aber auch um den Wrapper Dingesn aus dem Weg zu gehen mit arrays arbeiten :)
 

thE_29

Top Contributor
hrhr ;)

Ich mach das so, ist halt noch von C so ;)

Ihr seid ja alle verwöhnt von Java mit Arraylists usw. in C geht das net mal

Code:
int x[var];

Man muss vor dem Compileren schon eine fixe Anzahl reinschreiben, also

Code:
int x[20];

Tjojo, so ne ArrayList muss man sich in C++ halt selber schreiben, aber mit den Templates usw haut das schon hin, aber im normalen C, tjo, blöde Sache :bae:
 

Bleiglanz

Gesperrter Benutzer
Mir drängt sich die Frage auf warum man für Integer, String, usw...überhaupt einen public Konstruktor zulässt und so unnöte Objekte vermeidet?
Hä? Ohne Konstruktor?

Willst du die 2^32 möglichen Instanzen eines Integers irgendwo ablegen und bei bedarf zurückgeben? Das geht wohl nicht

Bleibt also ein private Konstruktor mit Factory-Methode, aber wie soll der aussehen?
Integer.newInstance(123434);
würde ja wohl nix bringen, da ist doch new Integer(123434) genauso gut??

Gäbe es den nicht könnte man Strings auch problemlos mit '==' vergleichen und es würde im Anfängerbereich
ungefähr 1000 Threads zum Thema Stringvergleich weniger geben
Ein Vergliech mit == hat bei Strings und den Wrapper-Klassen fast NIE einen Sinn, in Java 5 sogar noch weniger als früher (weitere Verwirrung durch boxing)

wie soll ein Prog funktionieren, dass alle Strings intern(); macht und dann bei jedem (dynamischen) neuen String den ganzen Stringpool durchsuchen muss -> das geht nicht!!

wenns dir leichter fällt: wie soll z.B. Double seine Instanzen verwalten, damit == äquivalent zu equals ist; mit endlichem Speicher ziemlich unmöglich...
 
S

stev.glasow

Gast
Ob man die nun mit == vergleichen kann oder nicht finde ich auch nicht wichtig. Aber wenn man das Integer.valueOf(int) schon von Anfang an so gehändelt hätte würde ein private Konstruktor doch schon Sinn machen.
 

thE_29

Top Contributor
Man hätte bei den Strings ja eigentlich auch den == operator überschreiben können ;>

Warum isn das eigentlich nicht gemacht worden? Weil der + operator ist ja auch überschrieben...

Wären halt viele Fragen weniger, warum das nicht geht wenn ich if(string == "HALLO") mache :D
 
S

stev.glasow

Gast
thE_29 hat gesagt.:
Man hätte bei den Strings ja eigentlich auch den == operator überschreiben können ;>

Warum isn das eigentlich nicht gemacht worden? Weil der + operator ist ja auch überschrieben...

Wären halt viele Fragen weniger, warum das nicht geht wenn ich if(string == "HALLO") mache :D
Weil man mit == nicht den Inhalt vergleicht sondern ob es die gleiche Referenz ist.
Sonst würde ja 'new String("hä") == new String("hä")' true ergeben, und das wär irgendwie ... naja
 

thE_29

Top Contributor
Naja, hast recht, dann würde Referenz vergleich wegfallen. Aber braucht man den so oft??

Manchmal isses für mich ärgerlich das man keine Operatoren überladen kann, das war in C++ super ;)

Aber was solls, man kommt auch ohne aus :D
 
S

stev.glasow

Gast
thE_29 hat gesagt.:
Naja, hast recht, dann würde Referenz vergleich wegfallen. Aber braucht man den so oft??

Manchmal isses für mich ärgerlich das man keine Operatoren überladen kann, das war in C++ super ;)

Aber was solls, man kommt auch ohne aus :D
Och Operatorenüberladen is Schnickschnack. :) Was ist verständlicher ohne groß in der Doku der entsprechenden Klasse zuschauen? a + b oder a.append(b)?
 

meez

Top Contributor
0xdeadbeef hat gesagt.:
Hier werden Referenzen verglichen, die ja nur dann gleich sind, wenn sie tatsächlich auf das selbe Objekt verweisen. Per "valueOf" erzeugt man also keine neuen Instanzen, wenn ein Objekt gleichen Inhalts bereits existiert.´
en...

axo, das habt ihr gemeint...
 

thE_29

Top Contributor
Es kommt darauf an was a+b machen soll ;)

Hast du zB 2 Klassen Mensch und du machst a + b kannst du halt sagen was dann rauskommen soll

soll sich nur das Gewicht zusammen zählen, oder soll das dann heißen sie sind verheiratet (sprich Namensänderung) usw

operatoren Überladen hat schon sinn (stimmt sie tragen zur Verwirrung bei, deswegen immer gut dokumentieren ;))
 
K

Kirsche

Gast
stevg hat gesagt.:
Das ist nicht ganz das gleiche, das was in dem Zitat erwähnt wird läuft "intern" ab, denn new String("hallo") == "hallo" ergibt ja false, aber trotzdem wird nur eine Zeichenkette gespeichert. (Kein Plan wer das jetzt Regel, hatte eigentlich angenommen das dass die VM macht und nicht der Compilier.)
Und das mit Integer.valueOf(int) läuft nicht so, das wurde einfach mit Java so programmiert.
[edit]
oder so ähnlich :?

new Strinf("hallo") wird zur Laufzeit erstellt "hello" kann er schon beim Compilieren umsetzen und behandelt er so komplett anders.
Deswegen der Unterschied!

Gruß
Kirsche
 
S

stev.glasow

Gast
Kirsche hat gesagt.:
new Strinf("hallo") wird zur Laufzeit erstellt "hello" kann er schon beim Compilieren umsetzen und behandelt er so komplett anders.
Aha also doch der Compiler, aber die Zeichenkette ist doch aber trotzdem nur einmal im Speicher vorhanden, oder?

Kirsche hat gesagt.:
Deswegen der Unterschied!
Welchen Unterschied meinst du? Ich hatte von dem Unterschied zwischen String und Integer.valueOf(int) gesprochen.


Oder habe ich das jetzt ganz falsch verstanden, worauf du hinnaus willst?
 
S

Spacerat

Gast
Schon vom StringBuffer gehört? (Nein, ich meine nicht die gleichnamige Java-Klasse!)

Beim 1. Instanzieren eines Strings (z.B. String s1="Hello") wird durch die JVM automatisch ein StringBuffer angelegt. die Variable s1 selber erhält nur einen (Offset-??) Zeiger auf die Stelle im StringBuffer wo "Hello" beginnt. Mit String s2= new String (s1); kann man eine zweite Stringvariable instanzieren. Die sollte ja nun den selben Inhalt wie s1 haben. Aber man kann machen was man will (s1 == s2; s1 == "Hello"; s2 == "Hello"), alle "Vergleiche" ergeben false (JDK 1.4.2_05). Lediglich "Hello" == "Hello" ergibt true. Klar... Hier vergleicht die JVM den absoluten Start der Zeichenkette "Hello" im StringBuffer mit... ähh... dem absoluten Start der Zeichenkette "Hello" im StringBuffer.

Als fortgeschrittener Java-Progger kommt man übrigens aus Performancegründen (laut Java-Handbuch 3.0) recht schnell von der vorwiegenden Benutzung der Klasse String weg, da intern ohnehin nur mit StringBuffer gearbeitet wird.

Man kann sich ja mal den Spaß machen, und sich einen Code erstellen, in dem Zig-Mal ein und die selbe Zeichenkette vorkommt, einige Vergleiche damit anstellen, diesen anschließend Kompilieren und sich den erstellten Bytecode in einem Hex-Editor ansehen bzw. nach der Zeichenkette suchen. Bei eigenen Versuchen konnte ich eine derartig verwendete Zeichenkette stets nur einmal finden.
 

Bleiglanz

Gesperrter Benutzer
richtig ist:

wenn ein String mit s = new String("hello") erzeugt wird, dann wird auf keinen Fall der Konstantenpool verwendet, sondern IMMER neuer Speicher verbraten!

deshalb wird new String("x") == new String("x") immer false liefern

wenn der String literal im Quelltext vorkommt

String s = "x";

dann wird "x" vom javac schon in den Stringpool gelegt...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben