Globale Variablen in Java?

Alles, was sonst nirgendwo reinpasst

Beitragvon theTux » 18.11.07 22:48

Mitlerweile müsste das sogar mit allen Operatoren gehen. Empfehlenswert ist das trotzdem nicht...
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon thana » 19.11.07 16:40

fw hat geschrieben:"Integer x = new Integer(42)", x ist nun ein Objekt und wird per Reference übergeben (wogegen 42 (oder eine Variable vom Typ int) per Value übergeben worden wäre)

Neinneinnein, in Java wird *NIE* irgendwas by-reference übergeben. Es wir *IMMER* *ALLES* by-value übergeben.
Im Falle von Objekten wird aber natürlich nur die Referenz auf das Objekt übergeben, das aber auch by-value!
thana
 
Beiträge: 264
Registriert: 18.10.07 17:01

Beitragvon Lukul » 19.11.07 22:03

thana hat geschrieben:
fw hat geschrieben:"Integer x = new Integer(42)", x ist nun ein Objekt und wird per Reference übergeben (wogegen 42 (oder eine Variable vom Typ int) per Value übergeben worden wäre)

Neinneinnein, in Java wird *NIE* irgendwas by-reference übergeben. Es wir *IMMER* *ALLES* by-value übergeben.
Im Falle von Objekten wird aber natürlich nur die Referenz auf das Objekt übergeben, das aber auch by-value!


Eben, ist wohl ein beliebter Fehler, der schon so manchen Leuten Prüfungen gekostet hat.

Habs grad mal ausprobiert: Zumindest in Java 1.6 funktioniert sowas hier problemlos:

Code: Alles auswählen
Integer i = 24;
Integer j = 27;
if (i <= j) {
     System.out.println("i <= j");
}
Lukul
 
Beiträge: 425
Registriert: 23.09.05 19:13
Wohnort: Aachen

Beitragvon theTux » 19.11.07 23:12

Lukul hat geschrieben:Zumindest in Java 1.6 funktioniert sowas hier problemlos:

Code: Alles auswählen
Integer i = 24;
Integer j = 27;
if (i <= j) {
     System.out.println("i <= j");
}

Das hat so keine Aussagekraft. Denn wenn der <=-Operator nicht überladen ist, werden die Speicheradressen verglichen. Und da du i vor j deklariert hast, wird i mit einiger Sicherheit auch vor j im Speicher stehen.
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon fw » 19.11.07 23:33

thana hat geschrieben:Neinneinnein, in Java wird *NIE* irgendwas by-reference übergeben. Es wir *IMMER* *ALLES* by-value übergeben.
Im Falle von Objekten wird aber natürlich nur die Referenz auf das Objekt übergeben, das aber auch by-value!


Das ist mir völlig klar, da Coolcat das ja auch vor dir schon gesagt hat. Aber diese Kleinscheisserei ob das nun Call by Reference ist oder Call by Value wobei als Value eine Referenz übergeben wird... Ich glaube es war völlig klar was gemeint war...
Benutzeravatar
fw
 
Beiträge: 1356
Registriert: 17.05.06 19:37
Studiengang: Informatik (Dipl.)
Studiert seit: fertig
Anwendungsfach: Mathe

Beitragvon kb » 19.11.07 23:48

Es ist in sofern nicht egal (abgesehen von Prüfungsfragen), als dass man der übergebenen Variable nichts anderes zuweisen kannst, weil man eben keine Referenz übergeben kann!

--edit--
selbst wenn man Objekte übergibt (bei denen im Grunde ja wie gesagt nur die referenzierte Adresse übergeben wird), kann man nicht sagen "die Variable soll jetzt auf kein Objekt x sondern auf ein Objekt y zeigen".
"Auch wenn fünfzig Millionen Menschen etwas Dummes sagen, bleibt es trotzdem eine Dummheit."
"It doesn't matter if you win or lose, it's whether or not you beat the spread."
Benutzeravatar
kb
 
Beiträge: 1237
Registriert: 06.04.06 21:20
Wohnort: Aachen / Köln

Beitragvon Tempest » 20.11.07 00:16

Ergänzung:
Code: Alles auswählen
public class Test {
   static Integer i;
   
   static void test(Integer i) {
      i++; // oder i = 1337; oder i = new Integer("0815"); etc..
   }
   
   public static void main(String[] args) {
      Test.i = 42;
      test(Test.i);
      System.out.println(Test.i);
   }
}
Benutzeravatar
Tempest
 
Beiträge: 76
Registriert: 13.05.07 22:17
Studiengang: Informatik (M.Sc.)
Studiert seit: SS 07
Anwendungsfach: BWL

Beitragvon Lukul » 22.11.07 01:45

theTux hat geschrieben:
Lukul hat geschrieben:Zumindest in Java 1.6 funktioniert sowas hier problemlos:

Code: Alles auswählen
Integer i = 24;
Integer j = 27;
if (i <= j) {
     System.out.println("i <= j");
}

Das hat so keine Aussagekraft. Denn wenn der <=-Operator nicht überladen ist, werden die Speicheradressen verglichen. Und da du i vor j deklariert hast, wird i mit einiger Sicherheit auch vor j im Speicher stehen.


Ach, echt?
Code: Alles auswählen
public class Test {
        public static void main (String[] args) {
            Thread j = new Thread();
            Thread k = new Thread();

            if (j <= k) System.out.println("");
        }
}


Code: Alles auswählen
ln@igemyvuci:~$ javac Test.java
Test.java:6: operator <= cannot be applied to java.lang.Thread,java.lang.Thread
            if (j <= k) System.out.println("");
                  ^
1 error


Ich wüsste nicht, dass man in Java Speicheradressen vergleichen könnte.
Lukul
 
Beiträge: 425
Registriert: 23.09.05 19:13
Wohnort: Aachen

Beitragvon mirko » 22.11.07 11:11

Lukul hat geschrieben:Ich wüsste nicht, dass man in Java Speicheradressen vergleichen könnte.


java kann aber auch gar nix :P

naja, ok - da java die komplette verwaltung des speichers mehr oder weniger geheim hält und der benutzer da eh nicht viel dran ändern kann, macht es auch keinen sinn, speicheradressen zu vergleichen...
mirko
 
Beiträge: 1032
Registriert: 22.10.06 18:33
Studiert seit: WS 12/13

Beitragvon theTux » 22.11.07 13:04

Lukul hat geschrieben:Ach, echt?

Okay, ich gebe mich geschlagen - ausprobiert hatte ich das nicht.
Ich meine, es ging mal mit Java.
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon mgla » 28.11.07 13:30

Es ist so das Java gewisste Integer (mit großem I) cached. ich meine das waren die von -128 bis +128. Vermutlich weil die am häufigstem verwendet werden.

Deshalb ist:

Code: Alles auswählen
(Integer) 15 == (Integer) 15


true, aber:


Code: Alles auswählen
(Integer) 150 == (Integer) 150

false.
mgla
 
Beiträge: 121
Registriert: 07.01.07 14:31
Wohnort: Aachen

Beitragvon thana » 28.11.07 15:52

mgla hat geschrieben:Es ist so das Java gewisste Integer (mit großem I) cached. ich meine das waren die von -128 bis +128. Vermutlich weil die am häufigstem verwendet werden.

Deshalb ist:

Code: Alles auswählen
(Integer) 15 == (Integer) 15


true, aber:


Code: Alles auswählen
(Integer) 150 == (Integer) 150

false.


Das hat nichts mit "caching" zu tun, sondern nur das Wiederverwenden von Objekten, bei denen die JVM Beweisen kann, dass es in Ordnung ist ein Objekt wiederzuverwenden.

ABER zu Beachten ist dabei stets die JLS.
so ist z.B. laut JLS
Code: Alles auswählen
"foo" == "foo"

immer true, wohingegen
Code: Alles auswählen
 new String ("foo") == new String ("foo")

immer false ergeben muss.
Darüber hinaus ist auch keines der im letzten Vergleich erzeugten Objekte identisch mit dem Objekt aus dem ersten Vergleich.

Das liegt auf der einen Seite Begründet darin, dass ein String immutable ist und auf der anderen Seite darin, dass new IMMER ein futschneues Objekt erzeugt.

Warum nun der vergleich von (Integer)150 mit ebenselben Ausdruck schiefläuft weiß ich nicht. Ich schätze das wird in irgendwelchen Optimierungen begründet sein.
Die genaueren Umstände werde ich mal in Erfahrung bringen. MICH interessierts jedenfalls :)



theTux hat geschrieben:Ich meine, es ging mal mit Java.

Das ging übrigens nie. In der JLS steht eindeutig, dass die Argumente der relationalen Operatoren (im Kontext eines numerischen Vergleichs, man kann manche von ihnen ja auch zum Bit-Shifting verwenden) sich implizit in eine (numerischen) primitiven Typ casten lassen müssen.
thana
 
Beiträge: 264
Registriert: 18.10.07 17:01

Beitragvon thana » 28.11.07 16:24

Es hat also Tatsächlich was mit Caching zu tun im Falle des Integer-Vergleichs.
Wird ein int zu einem Integer gecastet wird die Methode Integer#valueOf(int i)
Aufgerufen.
Im Sourcecode zu dieser Methode sieht man dann auch schnell, wieso der "Vergleich von 15" als Objekt erfolgreich ist, der von 150 aber nicht:
Code: Alles auswählen
    public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }


Also ein klassischer Fall von "da sollte man sich besser nicht drauf verlassen!"
thana
 
Beiträge: 264
Registriert: 18.10.07 17:01

Beitragvon Tempest » 28.11.07 16:31

thana hat geschrieben:Die genaueren Umstände werde ich mal in Erfahrung bringen. MICH interessierts jedenfalls :)

JLS... [url=http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7]5.1.7 Boxing Conversion
[/url]
Benutzeravatar
Tempest
 
Beiträge: 76
Registriert: 13.05.07 22:17
Studiengang: Informatik (M.Sc.)
Studiert seit: SS 07
Anwendungsfach: BWL

Vorherige

Zurück zu Off-Topic