Forum: PC-Programmierung Java: Übergabeparameter wie in C++ beeinflussbar?


von Jemain (Gast)


Lesenswert?

Hi,
ist es in Java wie in C++ (via Referenz) möglich in einer 
Funktion/Methode Funktionsparameter "global" zu beeinflussen? Etwa in 
diesem Sinne (so klappts allerdings nicht):
1
...
2
int a = 2;
3
foo(a);
4
System.out.print(a);
5
...
6
7
//foo()
8
public void foo(int a){
9
    a=20;
10
}
11
...

Hier wird 2 ausgegeben. Ich suche nach einem Weg (ohne Arrays) den 
Parameter über die Scopes der Methode zu beeinflussen. Entsprechend 
sollte also 20 ausgegeben werden

von FBR (Gast)


Lesenswert?

Bin nicht der Experte, aber soweit ich weiß wird das sogar immer so 
gemacht wie du es willst - bei Objekten. Bei primitiven Datentypen aber 
nicht. Ersetzte einmal “int“ durch “Integer“ und versuch es nochmal.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Integer ist "imutable". Was einen natürlich nicht abhält einfach ein 
"Austauschobjekt" zu nutzen (und sei es AtomicInteger), sinnvoller (und 
universeller) wäre jedoch eine Rückgabe per return.

von TestX .. (xaos)


Lesenswert?

du musst mit objekten arbeiten, schau dir mal die klassen Double, 
Integer, etc. an

von FBR (Gast)


Lesenswert?

Läubi .. schrieb:
> Integer ist "imutable".

Das macht doch nichts, oder? “a“ ist ja nur eine Referenz, ist doch egal 
ob das Objekt dahinter geändert oder neu erzeugt wird.

>.Was einen natürlich nicht abhält einfach ein
> "Austauschobjekt" zu nutzen (und sei es AtomicInteger),

Ist das wirklich notwendig?

> sinnvoller (und
> universeller) wäre jedoch eine Rückgabe per return.

Gerade bei objektorientierter Programmierung ist das nicht immer 
“besser“.

von Sebastian-L (Gast)


Lesenswert?


von Klaus W. (mfgkw)


Lesenswert?

FBR schrieb:
> Bin nicht der Experte, aber soweit ich weiß wird das sogar immer so
> gemacht wie du es willst - bei Objekten. Bei primitiven Datentypen aber
> nicht. Ersetzte einmal “int“ durch “Integer“ und versuch es nochmal.

Hätte ich auch erwartet mit meinen rudimentären Java-Kenntnissen, aber 
iss nich!

Habe mal ein Mini-Javaprogramm gestrickt, das eine Zahl erstens als int 
übergibt und ändern lässt, zweitens als Integer, und drittens als Obiekt 
einer eigenen Klasse (MeinInteger).
Bei 1 & 2 wird der Wert beim Aufrufer nicht geändert, bei 3 dann doch:

MeinInteger.java:
1
public class MeinInteger
2
{
3
    int get()
4
    {
5
        return wert;
6
    }
7
8
    void set( int neuerWert )
9
    {
10
        wert = neuerWert;
11
    }
12
13
    int   wert;
14
};

t.java:
1
import java.util.*;
2
3
public class t
4
{
5
    static void f_primitiv( int i )
6
    {
7
        i = 42;
8
        System.out.println( "f_primitiv: i ist " + i );
9
    }
10
11
    static void f_Integer( Integer i )
12
    {
13
        i = 42;
14
        System.out.println( "f_Integer: i ist " + i );
15
    }
16
17
    static void f_meinInteger( MeinInteger i )
18
    {
19
        i.set( 42 );
20
        System.out.println( "f_meinInteger: i ist " + i.get() );
21
    }
22
23
    public static void main( String args[] )
24
    {
25
        int int_zahl = 1;
26
        f_primitiv( int_zahl );
27
        System.out.println( "int_zahl ist " + int_zahl );
28
29
        Integer Integer_zahl = new Integer( 1 );
30
        f_Integer( Integer_zahl );
31
        System.out.println( "Integer_zahl ist " + Integer_zahl );
32
33
        MeinInteger meinInteger = new MeinInteger();
34
        meinInteger.set( 1 );
35
        f_meinInteger( meinInteger );
36
        System.out.println( "meinInteger ist " + meinInteger.get() );
37
    }
38
39
}

Ausgabe:
1
klaus@vdr2:~ > javac t.java MeinInteger.java && java t
2
f_primitiv: i ist 42
3
int_zahl ist 1
4
f_Integer: i ist 42
5
Integer_zahl ist 1
6
f_meinInteger: i ist 42
7
meinInteger ist 42

Das ist doch krank.
Soll noch einer sagen, C++ wäre unlogisch.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Klaus Wachtler schrieb:
> FBR schrieb:
>> Bin nicht der Experte, aber soweit ich weiß wird das sogar immer so
>> gemacht wie du es willst - bei Objekten. Bei primitiven Datentypen aber
>> nicht. Ersetzte einmal “int“ durch “Integer“ und versuch es nochmal.
>
> Hätte ich auch erwartet mit meinen rudimentären Java-Kenntnissen, aber
> iss nich!

Ich (der ebenfalls nicht viel Ahnung von Java hat ;-)) würde sagen, dass
in deinem Beispiel
1
    static void f_Integer( Integer i )
2
    {
3
        i = 42;
4
        System.out.println( "f_Integer: i ist " + i );
5
    }

mit i=42 ein neues Objekt angelegt wird, während das übegebene seinen
Wert behält. Da die Klasse Integer keine Set-Methode enthält, gibt es
keine Möglichkeit, ein Integer-Objekt zu modifizieren. Das ist wohl das,
was Läubi meinte mit

> Integer ist "imutable".

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Hätte ich auch erwartet mit meinen rudimentären Java-Kenntnissen,
> aber iss nich!
Was hättest du in C++ den erwartet wenn du einer Referenzvariablen ein 
neues Objekt zuweist?

Klaus Wachtler schrieb:
> Das ist doch krank.
Nein ist es nicht. Du bekommst eine Kopie eines "Pointer" welcher auf 
einen Integer zeigt und diesem weist du einen neuen Wert zu, wieso ist 
deine Erwartung, dass sich der ursprünglich referenzierte Wert ändert.

> Soll noch einer sagen, C++ wäre unlogisch.
Das sit nicht unlogisch, sondern mit falschen Annahmen an ein nicht 
existentes Problem herangegangen.
Bloss weil C/C++ es erlaubt bei (vermeintlichem) Bedarf beliebig im 
Speicher herumzupfuschen muß das nicht für alle anderen Sprachen auch 
gelten.

Klaus Wachtler schrieb:
> und drittens als Obiekt
> einer eigenen Klasse (MeinInteger)
Was die völlig korrekte Lösung ist (optimaler weise sollte deine Klasse 
noch von Number ableiten ;-), vorausgesetzt der Anwendungsfall ist 
genauso wie beschrieben und kein Fall von "premature optimization".

Nur der vollständigkeit halber, im zweiten Beispiel steht eigentlich
i = new Integer(42), was dir der Compiler netterweise abnimmt.

Yalu X. schrieb:
> Ich würde sagen, dass
> in deinem Beispiel
> [...]
vollkommen korrekt.

FBR schrieb:
> Gerade bei objektorientierter Programmierung ist das
> nicht immer “besser“.
Erklärung? Klaus hat ja den "OO" Weg aufgezeigt das zu lösen, warum das 
"direkte" manipulieren eines primitiven Datentyps (welcher in einer 
perfekten OO-Welt nicht existieren dürfte) jetzt besser sein soll 
erschließt sich mir nicht.

Yalu X. schrieb:
> Da die Klasse Integer keine Set-Methode enthält, gibt es
> keine Möglichkeit, ein Integer-Objekt zu modifizieren. Das ist wohl das,
> was Läubi meinte mit
>
>> Integer ist "imutable".

Korrekt, außerdem ist Integer auch noch final, es kann also keine 
"bösen" Ableitungen geben, welche dieses wieder umgehen, das ist aber 
wirklich schon etwas weit gegriffen.

von Klaus W. (mfgkw)


Lesenswert?

Läubi .. schrieb:
> Was hättest du in C++ den erwartet wenn du einer Referenzvariablen ein
> neues Objekt zuweist?

Meine Erwartung war, daß in der zweiten Funktion i eine Referenz ist auf 
die Variable beim Aufrufer (soweit wohl auch noch richtig) und mit i=42 
die Variable geändert wird (wohl falsch) - stattdessen wird das i der 
Funktion von der Variablen beim Aufrufer entkoppelt und verweist auf ein 
heimlich neu beschafftes Integer mit dem Wert 42, obwohl ich nirgends 
ein new gemacht habe.

Dank meiner schweren C++-Kindheit ist das überraschend, weil eine 
Referenz dort nie umgebogen wird.
Eine Zuweisung ändert dort einen Wert, nicht die Referenz (auch wenn 
eine Initialisierung aussehen kann wie eine Zuweisung, das ist auch in 
C++ unelegant).

Krank finde ich vor allem, daß primitive Datentypen generell anders 
gehandhabt werden (call by value) als Objekte (call by reference).
Manchmal ist das eine sinnvoll, mal das andere, und bei primitiven eher 
CBV. Aber deshalb komplett unterschiedliches Verhalten zu diktieren, 
finde ich höchst unelegant seitens der Sprache.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Aber deshalb komplett unterschiedliches Verhalten zu diktieren,
> finde ich höchst unelegant seitens der Sprache
Das siehst du falsch! Das Verhalten ist in allen Fällen gleich, der 
Unterschied ist der, dass alle primitiven (und alle Objektwrapper) 
konstant sind und keine setter haben, in deinem Beispiel 3 wäre der 
äquivalente Code:
1
static void f_meinInteger( MeinInteger i )
2
    {
3
        i = new MeinInteger()
4
        i.set( 42 );
5
        System.out.println( "f_meinInteger: i ist " + i.get() );
6
    }
Und auch in diesem Falle würde die Funktion nicht das Funktionsargument 
ändern (was sich auch nicht tut, sonder sie Ändert eben das Objekt auf 
welches das Argument zeigt, wenn das Objekt setter hat. Wenn du diesem 
(lokalem) "Zeiger" aber ein neues Objekt zuweist, sollte es nicht 
verwunderlich sein, dass dies keine Auswirkung auf den Aufrufer hat.

Wenn man dieses verhindern möchte kann man den Parameter als final 
deklarieren, was in deinem Beipiel 2 mit dem Integer zu einem 
Compilefehler führt.

In C++ würde man wohl sagen, dass alle Referenzen auf primitive 
Datentypen automatisch "const" sind.

Klaus Wachtler schrieb:
> Dank meiner schweren C++-Kindheit ist das überraschend,
> weil eine Referenz dort nie umgebogen wird.
... werden kann :-)
In Java ist das aber eher wie ein Pointer, welcher auf ein Objekt zeigt.

Klaus Wachtler schrieb:
> obwohl ich nirgends
> ein new gemacht habe.
Jeder der C++ macht sollte sich klar sein, das der Compiler halt ab und 
an sachen "heimlich" macht und Objekte kopiert, oder es einem durch 
typumwandlung "vereinfacht", und genau das ist hier der einzige Fall 
in Java, nämlich das seit neuestem primitive Typen automatisch 
"gewrappt" werden falls nötig.
http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

von Klaus W. (mfgkw)


Lesenswert?

Du kannst natürlich versuchen, mir das in schönen Worten schmackhaft zu 
machen, aber:

Läubi .. schrieb:
> In C++ würde man wohl sagen, dass alle Referenzen auf primitive
> Datentypen automatisch "const" sind.

... überzeugt mich auch nicht vom kohärenten Verhalten zwischen 
primitiven Daten und Objekten.

:-)

von UR-Schmitt (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> ... überzeugt mich auch nicht vom kohärenten Verhalten zwischen
> primitiven Daten und Objekten.

Das ist doch eigentlich nur die Besonderheit daß String (und auch 
Integer wie ich gerade gelernt habe) immutable sind. Also nicht 
veränderbar.
Das wurde (meines Erachtens) eingeführt, weil in Java eben alle Objekte 
automatisch als Referenz übergeben werden und es aber zu ständigen 
Fehlern kommt wenn diese Objekte verändert werden dürfen. Die 
Alternative wäre, daß der Programmierer jeder Unterfunktion (von der er 
nicht weiß was sie mit dem String macht eine Kopie übergeben müsste wenn 
er keine Änderung wünscht.

Ja das ist eine Besonderheit und die muss man einfach lernen.
Sage mir nur C hätte keine Besonderheiten :-), ich sag nur daß z.B. ein 
Struct quasi auch eine Objektdefinition ist nur mit Einschränkungen.

von Marwin (Gast)


Lesenswert?

Klaus, du verstehst offensichtlich nichts von Java und auch nicht viel 
von C++ und machst hier ein riesiges Fass auf...

von Klaus W. (mfgkw)


Lesenswert?

ok, scheint so zu sein, dann trinke ich es lieber aus.
Prost!

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

UR-Schmitt schrieb:
> Das ist doch eigentlich nur die Besonderheit daß String (und auch
> Integer wie ich gerade gelernt habe) immutable sind

Es gibt einfach nur keine Möglichkeit (wie in C/C++) eine 
Speicherstelle zu modifizieren, also hat ein Aufrufer, welcher ein 
Objekt/Datentyp/... erhält, welches keine Methoden oder public Member 
hat um den inneren Zustand zu verändern nun mal keine Möglichkeit dies 
zu tun.

Klaus Wachtler schrieb:
> Du kannst natürlich versuchen, mir das in schönen Worten
> schmackhaft zu machen
Ich wollte nur versuchen das Verhalten ein Stückweit zu erklären, um es 
richtig zu Verstehen müsste man sich die VM Spezifikation mal zu Gemüt 
führen (ist recht interessant).

UR-Schmitt schrieb:
> Ja das ist eine Besonderheit und die muss man einfach lernen.
Wie gesagt, das ist nichts besonderes sondern ergibt sich rein aus den 
"normalen" Umständen.

Wenn ich in C eine Funktion habe:
1
void tuWas(int i) {
2
 i = 7;
3
}
 dann erwarte ich ja auch nicht, dass sich für den Aufrufer etwas 
ändert. Das C halt (wie schon gesagt) noch zusätzlich die Möglichkeit 
bietet direkt und ungeprüft in die Speicherzelle zu schreiben wo der 
Aufrufer ggf. platz für einen int geschaffen hat ist etwas anderes...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Läubi .. schrieb:
> In Java ist das aber eher wie ein Pointer, welcher auf ein Objekt zeigt.

Ja, ich glaube, es bringt viel für's Verständnis, wenn man die Java-
Referenzen mit den C++-Pointern gleichsetzt, denn die C++-Referenzen
sind wirklich etwas völlig anderes. Wenn man dann noch den '.'-Operator
in Java durch ein '->' in C++ ersetzt denkt, passt alles wieder perfekt:

- Dere Operator '=' kopiert keine Inhalte, sondern weist einer Variablen
  einen neuen Objekt-Pointer zu. Genau wie in C++.

- Die Übergabe als Methodenargument erfolgt call-by-value. Genau wie in
  C++.

- Der Operator '==' vergleicht den Speicherort und nicht den
  Speicherinhalt. Genau wie in C++.

- ...

Der Hauptunterschied zwischen Java- und C++-Pointern besteht darin, dass
in Java sämtliche Operatoren zur Pointer-Arithmetik sowie zur Umwandlung
von Integers in Pointer und umgekehrt weggelassen wurden.

von UR-Schmitt (Gast)


Lesenswert?

Läubi .. schrieb:
> UR-Schmitt schrieb:
>> Das ist doch eigentlich nur die Besonderheit daß String (und auch
>> Integer wie ich gerade gelernt habe) immutable sind
>
> Es gibt einfach nur keine Möglichkeit (wie in C/C++) eine
> Speicherstelle zu modifizieren, also hat ein Aufrufer, welcher ein
> Objekt/Datentyp/... erhält, welches keine Methoden oder public Member
> hat um den inneren Zustand zu verändern nun mal keine Möglichkeit dies
> zu tun.

Stop, ich hatte mich jetzt nicht auf die automatische Kapselung von int 
i durch ein Integer bezogen (Autoboxing), sondern darauf:

Klaus Wachtler schrieb:
> Integer Integer_zahl = new Integer( 1 );
>         f_Integer( Integer_zahl );
>         System.out.println( "Integer_zahl ist " + Integer_zahl );

Es funktioniert ja auch nicht mit einem Integer Objekt. Der Grund ist 
daß es immutable ist.
Wobei ich nicht weiß ob ich dieses Autoboxing als Vorteil sehen soll.

von UR-Schmitt (Gast)


Lesenswert?

Yalu X. schrieb:
> Ja, ich glaube, es bringt viel für's Verständnis, wenn man die Java-
> Referenzen mit den C++-Pointern gleichsetzt, denn die C++-Referenzen
> sind wirklich etwas völlig anderes.

Man sucht natürlich immer nach Analogien um sich das Lernen/Umsteigen 
leichter zu machen.
Aber eigentlich wäre der saubere Weg möglichst gar nicht in Analogien zu 
denken sondern die Sprache wie sie ist zu lernen.
Ja ich weiß, man macht das quasi automatisch :-)

von Karl H. (kbuchegg)


Lesenswert?

> Nur der vollständigkeit halber, im zweiten Beispiel steht
> eigentlich
> i = new Integer(42)
> was dir der Compiler netterweise abnimmt.

Eigentlich nicht.
Das steht eigentlich

 i = Integer.ValueOf(42);

das Autoboxing.Und dieses Autoboxing bringt wieder seine eigenen 
Probleme mit sich.

http://openbook.galileocomputing.de/javainsel9/javainsel_09_002.htm#mj9aaef31dce82a3daebaeb79ea69bfab2

(Scrollt auch noch ein wenig runter zum Abschnitt "Mehr Probleme als 
Lösungen?".
Ohne jetzt Java-Bashing betreiben zu wollen, hab ich mir als C++ 
Programmierer dann doch verwundert die Augen gerieben, bei dem was ich 
da gelesen habe. Wenn die Java Fraktion das nächste mal auf C++ 
herdrischt und alles als so kompliziert und unlogisch bezeichnet, reibe 
ich denen das mal unter die Nase)

Was mir nicht klar ist:
Da treibt man Aufwand um die Basistypen in Klassen zu verpacken und dann 
verhalten sich diese Klassen wieder ganz anders als die Klassen, die ich 
selber schreibe. Wo ist da die Durchgängigkeit?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Eigentlich nicht.
> Das steht eigentlich

Was nur eine Optimierung für kleine Zahlen ist.

Karl Heinz Buchegger schrieb:
> hab ich mir als C++
> Programmierer dann doch verwundert die Augen gerieben

Wieso? Es folgt alles den ganz normalen Java Regeln. Und ich kann mich 
noch an ein C++ Beispiel vor kurzem hier erinnern wo sich die C++ 
eingeweihten selbst verwundert die Augen gerieben haben, es gibt wohl in 
jeder Sprache Eigenheiten die einen als Aussenstehender verwundern.

Karl Heinz Buchegger schrieb:
> Da treibt man Aufwand um die Basistypen in Klassen zu verpacken und dann
> verhalten sich diese Klassen wieder ganz anders als die Klassen, die ich
> selber schreibe. Wo ist da die Durchgängigkeit?

Sie verhalten sich nicht anders sondern haben einfach nur die 
Eigenschaft, dass bei Operationen diese automatisch in den Primitiven 
typ gewandelt werden oder zurück. Wer das nicht mag, darf in der IDE 
oder mit externen Tools gerne Sicherstellen dass sowas in "seinem" Code 
nicht benutzt wird.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> Karl Heinz Buchegger schrieb:
>> Eigentlich nicht.
>> Das steht eigentlich
>
> Was nur eine Optimierung für kleine Zahlen ist.

Hab ich zuerst auch gedacht. Dem ist aber nicht so.

>> Programmierer dann doch verwundert die Augen gerieben
>
> Wieso? Es folgt alles den ganz normalen Java Regeln.

Schon richtig. So sind die Regeln. Aber die muss man im Eifer des 
Gefechts beachten. Und wo da die Regellogik bei
1
Integer n1 = new Integer( 10 );
2
Integer n2 = Integer.valueOf( 10 );
3
Integer n3 = 10;
4
Integer n4 = 10;
5
System.out.println( n1 == n2 );   // false
6
System.out.println( n2 == n3 );   // true
7
System.out.println( n1 == n3 );   // false
8
System.out.println( n3 == n4 );   // true

ist, sehe ich ehrlich gesagt nicht wirklich.
So was ist ausser fehleranfällig doch nur noch fehleranfällig.

Oder das hier
1
Integer k1 = 127;
2
Integer k2 = 127;
3
System.out.println( k1 == k2 );   // true
4
Integer l1 = 128;
5
Integer l2 = 128;
6
System.out.println( l1 == l2 );   // false
(für alle Nicht-Link Leser. Es hängt vom tatsächlichen Wert ab, warum 
das einemal true rauskommt und das andere mal false. Das verhält sich 
für kleine Zahlen anders als für große Zahlen)


> Und ich kann mich
> noch an ein C++ Beispiel vor kurzem hier erinnern wo sich die C++
> eingeweihten selbst verwundert die Augen gerieben haben, es gibt wohl in
> jeder Sprache Eigenheiten die einen als Aussenstehender verwundern.

Zweifellos.
Vielleicht bewerte ich das auch über und in der Praxis ist das kein 
großes Problem (programmiere nicht in Java). Trotzdem kann ich mich 
damit ehrlich gesagt nicht anfreunden.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Hab ich zuerst auch gedacht. Dem ist aber nicht so.
Doch ist es, siehe API Dokumentation.

Karl Heinz Buchegger schrieb:
> So was ist ausser fehleranfällig doch nur noch fehleranfällig

Nein Objekte werden nicht per == verglichen sonst gibt es murks (s.o.)!

Karl Heinz Buchegger schrieb:
> Und wo da die Regellogik bei ist

> Integer n1 = new Integer( 10 );
Es wird ein neues Objekt angelegt welches (angenommen) an Speicherstelle 
1 liegt.
> Integer n2 = Integer.valueOf( 10 );
Es wird ein (von der valueOf Funktion gechacheds) Objekt zurückgegeben 
welches (angenommen) an der Speicherstelle 2 liegt.
> Integer n3 = 10;
> Integer n4 = 10;
Equivalent zu n2 = Integer.valueOf( 10 ), allso zeigen n3 und n4 auf 
Speicherstelle 2

Und wenn man das jetzt ersetzt steht im Folgenden:

Karl Heinz Buchegger schrieb:
> System.out.println( 1 == 2 );   // false
> System.out.println( 2 == 2 );   // true
> System.out.println( 1 == 2 );   // false
> System.out.println( 2 == 2 );   // true

Was ist daran unlogisch? "Unlogisch" ist nur, das bei solchen Beispielen 
immer implizit die implementierung der Sun JRE angenommen wird, welche 
nämlich wirklich die 256 ersten Zahlen cached, das wird von der API 
aber überhauptnicht gefordert.
>> as this method is likely to yield significantly
>> better space and time performance by caching frequently
>> requested values
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29
Es wäre also durchaus auch legitim, das die Methode ALLE jemals 
angeforderten Integer instanzen cached und diese dort zurückgibt, in 
diesem Fall wäre das Ergebnis im Beispiel immer true!

Karl Heinz Buchegger schrieb:
> Oder das hier
Siehe oben, hier wird auf ein Spezifikum der JRE Implementierung von Sun 
vertraut.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
>
> Was ist daran unlogisch?

Offenbar haben wir verschiedene Vorstellungen davon, was man alles im 
Hinterkopf behalten muss, wenn man Programmcode liest. :-)

> "Unlogisch" ist nur, das bei solchen Beispielen
> immer implizit die implementierung der Sun JRE angenommen wird, welche
> nämlich wirklich die 256 ersten Zahlen cached, das wird von der *API*
> aber überhauptnicht gefordert.

?
Das macht es ja dann noch schlimmer, wenn dieses Problem auftreten kann 
aber nicht muss.

Ok, ich hör auf. Ich versteh von Java zu wenig und wollte nur meine 
Verwunderung darüber Ausdruck verleihen.

Gibt es eigentlich einen Grund, warum Integer immutable ist?

von UR-Schmitt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ohne jetzt Java-Bashing betreiben zu wollen, hab ich mir als C++
> Programmierer dann doch verwundert die Augen gerieben,

Ich auch wie oben schon gesagt. Als ich das gesehen habe war mein erster 
Gedanke: "Was haben die geraucht".
Aber das habe ich auch gedacht, als ich das erste mal den 
Referenzoperator in C++ gesehen habe, oder daß ein struct jetzt eine 
Lightwight Klasse sein soll...

Ich habe Autoboxing nie vermisst und werde es wenn irgendmöglich 
weiterhin vermeiden.

Karl Heinz Buchegger schrieb:
> Vielleicht bewerte ich das auch über und in der Praxis ist das kein
> großes Problem
Kann zu fies zu findenen Fehlern führen und bringt wie gesagt für mich 
eigentlich keine Vorteile. (Programmiere fast ausschließlich in Java)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> was man alles im
> Hinterkopf behalten muss
Man sollte wissen, dass man keine Pointer/Referenzen mit == vergleicht, 
in C geht das auch schief wenn ich zwei Pointer vergleiche die zwar 
beide auf einen Int mit dem Wert 5 zeigen aber an unterschiedlicher 
Adresse...

Karl Heinz Buchegger schrieb:
> Das macht es ja dann noch schlimmer, wenn dieses Problem
> auftreten kann aber nicht muss.
Nein, das ist einfach ein Programmierfehler, s. o. es ist nicht Aufgabe 
der Sprache jede Dummheit vom Programmierer fernzuhalten.

Karl Heinz Buchegger schrieb:
> Gibt es eigentlich einen Grund, warum Integer immutable ist?
Es gibt Fälle wo man ein Objekt Anstelle eines primitiven typen 
benötigt, dafür sollen die Wrappetypes dienen, und da eine 7 eben eine 7 
ist und nicht aufeinmal eine 99 hat man sich dafür entschieden, ist in 
der Praxis aber auch nahezu nie ein Problem, es steht jedem frei sich 
"seinen" MutableInteger zu definieren, und diesen von Number abzuleiten.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Läubi .. schrieb:
> Man sollte wissen, dass man keine Pointer/Referenzen mit == vergleicht

In einer Sprache wie Java, die explizit versucht, Implementierungs-
aspekte vom Programmierer fernzuhalten, sollte es eigentlich den
'=='-Operator für Referenzen (bzw. Pointer) gar nicht geben. Er stellt
insofern einen Grenzfall zur (in Java nicht vorgesehenen) Pointer-
Arithmetik dar, dass er zwar keinen Pointer als Ergebnis liefert, das
Ergebnis jedoch von der Art und Weise, wie Objekte im Speicher abgelegt
werden, abhängt.

Vermutlich lautet die Regel so:

- Wenn zwei Objekte unterschiedlichen Inhalt haben, liefert '==' immer
  false.

- Wenn das eine Objekt durch direkte oder indirekte Zuweisung mit '='
  oder die Übergabe als Methodenargument aus dem anderen Objekt
  entsteht, liefert '==' immer true.

- In allen anderen Fällen ist ist das Ergebnis von '==' implementations-
  abhängig.

Aber genau dieses "implementationsabhängig" hat in Java eigentlich
nichts zu suchen, zumal der Compiler diesen dritten Fall nicht ohne
weiteres erkennen und deswegen nicht einmal eine entsprechende Warnung
ausgeben kann.

von Yalu X. (yalu) (Moderator)


Lesenswert?

UR-Schmitt schrieb:
> Aber eigentlich wäre der saubere Weg möglichst gar nicht in Analogien zu
> denken sondern die Sprache wie sie ist zu lernen.

Ich finde das Denken in Analogien schon sinnvoll (nicht nur bei der
Programmierung), da es eine Art Wiederverwendung von Wissen darstellt.

> Ja ich weiß, man macht das quasi automatisch :-)

Ich mache das sogar bewusst ;-)

Gerade wenn ein C++-Programmierer versucht, sich in Java einzuarbeiten,
ist es meiner Meinung nach unklug, bei null anzufangen. Viel besser ist
es, sich erst einmal darüber zu informieren, was in Java gleich wie in
C++ ist, und das ist sehr viel.

Natürlich gibt es nicht zu jedem Sprachelement in Java ein Analogon in
C++, sonst gäbe es keinen Grund, mit Java anzufangen. Deswegen sollte
man nicht tagelang nach Analogien suchen, wo möglicherweise gar keine
sind. Sonst blockiert man sich nur unnötig.

Nach dem man sich einen Überblick über die Gemeinsamkeiten der beiden
Sprachen verschafft hat, schaut man sich anschließend den Rest, also die
Unterschiede und Erweiterungen gegenüber C++ an. Dabei überlegt man sich
(oder liest es nach), was die Entwickler von Java wohl dazu bewegt hat,
diese Deltas einzuführen. Wenn man diese Gründe verstanden hat, hat man
auch Java als Ganzes verstanden.

Gerade durch die Konzentration auf die Unterschiede wird man ein echter
Java-Programmierer und nicht einer, der lediglich C++-Denkweisen in Java
umsetzt, frei nach dem Motto "You can write Fortran in any language".

Zudem kommt man mit dieser Vorgehensweise schneller zum Ziel, als wenn
man erst einmal alles, was man über Programmierung weiß, beiseite legt
und wie ein völliges Greenhorn an die Sache heran geht.

von Rolf Magnus (Gast)


Lesenswert?

Läubi .. schrieb:
> Karl Heinz Buchegger schrieb:
>> was man alles im
>> Hinterkopf behalten muss
> Man sollte wissen, dass man keine Pointer/Referenzen mit == vergleicht,
> in C geht das auch schief wenn ich zwei Pointer vergleiche die zwar
> beide auf einen Int mit dem Wert 5 zeigen aber an unterschiedlicher
> Adresse...

Naja, bei C++ gibt es eben eine genaue Trennung, welche Operationen sich 
auf den Zeiger und welche auf das Objekt auswirkt. Bei Java wirken sich 
dann die Operationen eigentlich implizit auf das Objekt aus, außer halt 
bei ==, da ist es dann stattdessen doch wieder der Zeiger.
Wie ist das eigentlich bei den primitiven Typen? Werden bei dem 
folgenden auch Adressen vergleichen, oder ist es da dann wieder anders?
1
int i = 2;
2
int j = 2;
3
System.out.println( i == j );

> Karl Heinz Buchegger schrieb:
>> Das macht es ja dann noch schlimmer, wenn dieses Problem
>> auftreten kann aber nicht muss.
> Nein, das ist einfach ein Programmierfehler, s. o. es ist nicht Aufgabe
> der Sprache jede Dummheit vom Programmierer fernzuhalten.

Ich dachte immer, daß sich Java genau das als Aufgabe gesetzt hat.

> Karl Heinz Buchegger schrieb:
>> Gibt es eigentlich einen Grund, warum Integer immutable ist?
> Es gibt Fälle wo man ein Objekt Anstelle eines primitiven typen
> benötigt,

Schon hier kommt bei mir die Frage auf, warum ich überhaupt eine Klasse 
statt eines int brauchen könnte, um einen int-Wert zu speichern, also 
warum die primitiven Typen irgendwie anders sind.

> dafür sollen die Wrappetypes dienen, und da eine 7 eben eine 7
> ist und nicht aufeinmal eine 99 hat man sich dafür entschieden,

Das Argument leuchtet mir nicht ein. Das macht man bei den primitiven 
Typen ja auch nicht so - wäre ja auch unsinnig (int i = 7, und dann muß 
i für immer und ewig 7 bleiben, "weil eine 7 eben eine 7 ist"...)

> ist in der Praxis aber auch nahezu nie ein Problem, es steht jedem frei
> sich "seinen" MutableInteger zu definieren, und diesen von Number
> abzuleiten.

Dafür einen extra Typ definieren zu müssen finde ich aber doch etwas 
umständlich für so was simples.

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:

>>> Gibt es eigentlich einen Grund, warum Integer immutable ist?
>> Es gibt Fälle wo man ein Objekt Anstelle eines primitiven typen
>> benötigt,
>
> Schon hier kommt bei mir die Frage auf, warum ich überhaupt eine Klasse
> statt eines int brauchen könnte, um einen int-Wert zu speichern, also
> warum die primitiven Typen irgendwie anders sind.

Da hatte man wohl (und ich denke nicht so ganz zu unrecht) Angst vor 
Performance-Verlusten.

>> dafür sollen die Wrappetypes dienen, und da eine 7 eben eine 7
>> ist und nicht aufeinmal eine 99 hat man sich dafür entschieden,
>
> Das Argument leuchtet mir nicht ein.

Mir auch nicht.

Aber ok, Java ist nicht meine Sprache und wird es auch nie werden.
(Und wenn ich eine Konklusio aus diesem Tread mitnehme, dann die, dass 
MS bei C# wohl einiges 'richtiger' gemacht hat. Nicht das ich jetzt zu 
einem C# Fan mutiert wäre, so ist das dann auch wieder nicht. Aber ein 
Blick über den Zaun hat noch niemandem geschadet. Und schliesslich gibt 
es ja auch in C++ jede Menge Kritikpunkte)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> In einer Sprache wie Java, die explizit versucht, Implementierungs-
> aspekte vom Programmierer fernzuhalten, sollte es eigentlich den
> '=='-Operator für Referenzen (bzw. Pointer) gar nicht geben
Manchmal benötigt man das, und es ist durchaus legitim, z.B. wenn du nun 
wissen möchtest ob es sich und das selbe und nicht nur um das 
gleiche Objekt handelt.

Yalu X. schrieb:
> Vermutlich lautet die Regel so
Nein, es gibt nur eine definierte Menge von Operatoren auf Datentypen, 
und für Object ist es halt so definiert, das die Objektidentität 
verglichen wird.

Yalu X. schrieb:
> Aber genau dieses "implementationsabhängig"
Es ist nicht implementationsabhängig, das ganze ist ein konstruiertes 
Beispiel wo etwas anderes herauskommt bei einer Operation als man im 
ersten Augenblick bei nicht genauem hinschauen erwarten würde.

Rolf Magnus schrieb:
> Naja, bei C++ gibt es eben eine genaue Trennung,
> welche Operationen sich auf den Zeiger und welche
> auf das Objekt auswirkt
Gibt es bei Java auch, nur weil man sie nicht kennt, oder sie zufällig 
gleich der ist welche man von andere Seite her kennt heist nicht das es 
unlogisch ist.

> Bei Java wirken sich  dann die Operationen
> eigentlich implizit auf das Objekt aus
Nein! Es gibt (s.o.) eine definierte Liste von definierten Operatoren.

Rolf Magnus schrieb:
> Wie ist das eigentlich bei den primitiven Typen? Werden bei dem
> folgenden auch Adressen vergleichen, oder ist es da dann wieder anders?
Es ist nicht "wieder" anders, sondern es wird die auf int definierte 
Operation == durchgeführt. Diese ist aber nicht die gleiche wie für 
Object und auch nicht die gleiche wie z.B. für boolean.

Rolf Magnus schrieb:
> Schon hier kommt bei mir die Frage auf, warum ich überhaupt eine Klasse
> statt eines int brauchen könnte,
Z.B. analog wie in C++, weil eine int variable nicht 'null' sein kann 
oder eine Rückgabe einer Funktion die int zurückgibt nicht 'null' sein 
kann.

Rolf Magnus schrieb:
> Das Argument leuchtet mir nicht ein
Variable != Objekt/Wert. Schreib doch mal in C rein 7 = 5, da wird sich 
der Compiler auch beschweren, da man dem "Wert" 7 keinen neue Bedeutung 
zuweisen kann, das hat man halt versucht nachzubauen, insbesondere da es 
in Java kein 'const' gibt.

Rolf Magnus schrieb:
> Dafür einen extra Typ definieren zu müssen finde ich aber
> doch etwas umständlich
Was ist den "Dafür", der TE schreibt ja nicht mal wozu er das haben 
will, diese Operation "Speicherzelle eines Int" an eine Funktion zu 
übergeben gibt es schlich nicht, und man benötigt sie auch in der Regel 
nicht. Und für die 0,001% der Fälle wo es dann doch unumgänglich wäre 
kann man sich dann halt behelfen, wie gesagt es gibt schon diese Typen 
siehe
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicInteger.html
auch wenn dieser noch mehr bietet und nicht automatischem (un)boxing 
unterliegt.

Karl Heinz Buchegger schrieb:
> Und wenn ich eine Konklusio aus diesem Tread mitnehme, dann die, dass
> MS bei C# wohl einiges 'richtiger' gemacht hat.

Wenn man das daran festmacht, dass man einem Int per modifizierbarem 
pointer übergeben kann mag das wohl stimmen, in "normalen" Java 
Anwendungen arbeitet man aber mit Objekten und nicht mit einzelnene 
int's die nicht per returnvalue übergeben werden können...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Läubi .. schrieb:
> Yalu X. schrieb:
>> Vermutlich lautet die Regel so
> Nein, es gibt nur eine definierte Menge von Operatoren auf Datentypen,
> und für Object ist es halt so definiert, das die Objektidentität
> verglichen wird.

Ja schon. Aber wann sind zwei Objekte a und b identisch? Klar, wenn sie
an der gleichen Stelle im Speicher liegen.

Aber wann ist dies der Fall? Das wollte ich mit den aufgestellten Regeln
beschreiben. Ob das tatsächlich so gemacht wird, dazu müsste man sich
die Sprachspezifiktion von Java genauer ansehen.

> Yalu X. schrieb:
>> Aber genau dieses "implementationsabhängig"
> Es ist nicht implementationsabhängig, das ganze ist ein konstruiertes
> Beispiel wo etwas anderes herauskommt bei einer Operation als man im
> ersten Augenblick bei nicht genauem hinschauen erwarten würde.

Ist denn garantiert, dass der Methodenaufruf Integer.valueOf(n) für
gleiche n immer die gleiche Objektreferenz zurückgibt?

Zumindest die API-Dokumentation macht hierzu keine definitive Aussage:

  "Returns a Integer instance representing the specified int value. If a
  new Integer instance is not required, this method should generally be
  used in preference to the constructor Integer(int), as this method is
  likely to yield significantly better space and time performance by
  caching frequently requested values."

Das hört sich für mich so an, dass die Gleichheit der zurückgegebenen
Referenzen u.a. davon abhängt, ob noch genügend Platz im Cache ist.

Somit ist doch die '=='-Operation für Referenzen implementationsabhän-
gig, wenn nicht sogar undefiniert?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Somit ist doch die '=='-Operation für Referenzen implementationsabhän-
> gig, wenn nicht sogar undefiniert?

Diese Schlussfolgerung verstehe ich nicht :-)
Die API sagt nur, dass entweder eine gechachte Instanz zurückgegeben 
wird oder eine neue erzeugt wird. Die '=='-Operation wird dadurch 
nicht beeinflusst.

Wenn ich zwei Objekte habe (hier sind es zufällig Integer, welche 
auch als int repräsentiert werden könnten) vergleichen möchte mache 
ich das eben über die equals Methode, dann kommt hier auch genau das 
erwartete Verhalten raus.
Der Fehler ist einfach, das hier Objektreferenzen verglichen werden 
obwohl Objektwerte verglichen werden sollten (oder dem Leser suggeriert 
wird=.

Yalu X. schrieb:
> Aber wann sind zwei Objekte a und b identisch? Klar, wenn sie
> an der gleichen Stelle im Speicher liegen

Da es ja scheinbar doch jetzt genau interessiert:
>> 15.21.3. Reference Equality Operators == and !=
>> At run-time, the result of == is true if the operand
>> values are both null or both refer to the same object or
>> array; otherwise, the result is false.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html

Wie festgestellt wird ob es sich um das selbe Objekt handelt bleibt 
der VM überlassen (das könnte z.B. eine ID sein welche intern gehalten 
wird), ich meine gelesen zu haben das in der OracleVM halt eine Art 
SpeicherstellenID genutzt wird.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

So ich habe mal ein Beispiel in C zusammengehackt, welches das gleiche 
"Problem" hat:
1
#include <stdio.h>
2
3
int* makePointer(int x) {
4
  static int ints[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
5
  if (x > -1 && x < 13) {
6
  return &ints[x];
7
  } else {
8
    return 0;
9
  }
10
}
11
12
void main()
13
{
14
  int x = 10;
15
  int* n1 = &x;
16
  int* n2 = makePointer( 10 );
17
  int* n3 = makePointer( 10 );
18
  printf("n1 = %i\n", *n1);
19
  printf("n2 = %i\n", *n2);
20
  printf("n3 = %i\n", *n3);
21
  printf("n1 == n2? : %s\n", (n1 == n2)?"true":"false");
22
  printf("n2 == n3? : %s\n", (n2 == n3)?"true":"false");
23
}
Ausgabe:
1
$ gcc cexample.c 
2
$ ./a.out 
3
n1 = 10
4
n2 = 10
5
n3 = 10
6
n1 == n2? : false
7
n2 == n3? : true
Also ist C genauso unlogisch wie Java ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Läubi .. schrieb:
> Da es ja scheinbar doch jetzt genau interessiert:

Ok, vermutlich reden wir deswegen aneinander vorbei, weil ich noch nicht
ganz verstanden habe, wozu der '=='-Operator in der Praxis genutzt wird.
Ich habe gedacht, dass er primär ein effizienter Ersatz für equals ist,
wobei aber für die Anwendbarkeit gewisse Voraussetzungen erfüllt sein
müssen, da sonst u.U. inhaltlich gleiche Objekte als verschieden angese-
hen werden. Wenn das aber tatsächlich die Intention '==' wäre, müssten
diese Voraussetzungen ja irgendwo niedergeschrieben sein.

Aber wahrscheinlich wird der Operator tatsächlich nur so verwendet, wie
du es zitiert hast, nämlich um festzustellen, dass zwei Objekte "the
same" sind. Nur, wozu braucht man so etwas? Hast du vielleicht ein
typisches Beispiel parat?

Eines, das mir auf die Schnelle einfällt, wäre folgendes:
1
  if(a == b || a.equals(b))
2
    // a und b sind inhaltlich gleich

Das Ganze wäre ein zu equals äquivalenter, aber evtl. effizienterer
Vergleich. Wobei eine gute Implementation von equals den '=='-Vergleich
aber ja schon beinhalten könnte.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Ich habe gedacht, dass er primär ein effizienter Ersatz für equals ist
Wie du schon geschrieben hast ist er das eben nicht, das sind zwei 
paar Schuhe.

Yalu X. schrieb:
> Wobei eine gute Implementation von equals den '=='-Vergleich
> aber ja schon beinhalten könnte.

Die default implementierung für equals sieht so aus:
1
return this == otherObject;

Yalu X. schrieb:
> Das Ganze wäre ein zu equals äquivalenter, aber evtl.
> effizienterer Vergleich
Genau so ist es. Man benötigt sowas hauptsächlich in Bibliotheken, 
brauchen tut man das auch, wenn Objekte zwar "gleich" sind, du aber den 
Index eines bestimmten Objektes ermitteln willst, im OSGi Framework wird 
es benötigt für set/unset Methoden welche eventuell ein replacement 
Objekt bereitstellen, sicher nichts was man ständig braucht, aber es 
gibt durchaus legitime Anwendungsfälle.

von UR-Schmitt (Gast)


Lesenswert?

Yalu X. schrieb:
> Ok, vermutlich reden wir deswegen aneinander vorbei, weil ich noch nicht
> ganz verstanden habe, wozu der '=='-Operator in der Praxis genutzt wird.

na ja er wird halt häufig bei primitiven Typen wie int, long genutzt. 
Insofern ist ein == bei Integer Objekten durchaus ein Fehler der einem 
passieren kann.
Das ist halt der etwas hybride Ansatz von Java mit den primitiven Typen 
und den Objekten. Smalltalk hat das meines WIssens nicht, dafür ist 
smalltalk dann auch deutlich langsamer, whärend man in Java richtig 
schnelle Routinen programmieren kann. (ja ich weiß C (++) ist schneller, 
aber ich hatte Beispiele wo quasi identischer C code ohne Optimierung 
auf Windows langsamer war).


Yalu X. schrieb:
> Eines, das mir auf die Schnelle einfällt, wäre folgendes:
>   if(a == b || a.equals(b))
>     // a und b sind inhaltlich gleich
>
> Das Ganze wäre ein zu equals äquivalenter, aber evtl. effizienterer
> Vergleich. Wobei eine gute Implementation von equals den '=='-Vergleich
> aber ja schon beinhalten könnte.
Wobei die direkte Lösung dann den Vorteil hätte daß man sich den 
Methodenaufruf spart, das ganze bei einer zeitkritischen Routine 
effizienter wäre.

von Klaus W. (mfgkw)


Lesenswert?

Läubi .. schrieb:
> Also ist C genauso unlogisch wie Java ;-)

Wieso das?
Du kannst in C/C++ Zeiger vergleichen, oder Werte.
Natürlich können zwei Zeiger unterschiedlich sein, aber trotzdem auf 
Elemente mit gleichem Wert verweisen. Das ist aber nicht überraschend 
m.E..

Es erscheint nur unlogisch, weil du etwas dreist schreibst:
1
printf("n1 = %i\n", *n1);
2
...
Also den Text n1 nimmst, aber den Wert *n1 ausgibst.
Mit den drei Ausgaben von n1, n2, n3 wird eine Gleichheit suggeriert, 
die es nicht gibt, nur um dann hinterher stolz festzustellen, daß n1==n2 
nicht gilt.

Das Unlogische an Java ist, daß man mit demselben == mal den Wert 
vergleicht (bei primitiven Datentypen) und mal die Identität feststellt, 
nicht die Gleichheit des Werts (bei Objekten), und mal ist es 
Glückssache, ob durch Optimierung zwei Dinge identisch sind oder nicht 
(jaja, ist nicht unlogisch, sondern wohldefiniert...)

Ebenso wie mal CBV und mal CBR bei Parameterübergabe, je nach Typ.
Wenn man dem Programmierer schon nicht die Wahl zwischen CBV und CBR 
lässt, weil der durchschnittliche Coder es eh nicht rafft, dann hätte 
man ihm solche Feinheiten auch nicht zumuten sollen.

Abgesehen davon: Der Vergleich mit C und C++ ist insofern unfair, als C 
aus der Steinzeit kommt und deshalb bis zu C++ noch viele Altlasten 
mitschleppt.
Dagegen ist Java wesentlich neuer und hatte die Chance, alles besser zu 
machen; zumal es auch noch wesentlich HW-abstrahierter ist.
Dann hätte man solche Ecken viellcith nicht unbedingt einbauen müssen.

Ich habe auch nie behauptet, daß C und C++ besonders saubere Sprachen 
wären - nur, daß Java auch seine Leichen im Keller hat.

Läubi .. schrieb:
> Also ist C genauso unlogisch wie Java ;-)

Darauf kann man sich einigen - sie nehmen sich nix :-)

Aber wie gesagt, habe ich ja eh keine Ahnung :-)

von UR-Schmitt (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Dagegen ist Java wesentlich neuer und hatte die Chance, alles besser zu
> machen; zumal es auch noch wesentlich HW-abstrahierter ist.
> Dann hätte man solche Ecken viellcith nicht unbedingt einbauen müssen.

Wie gesagt das wurde der Performance geschuldet.

Wie ist das eigentlich in c#? Ich habe da bis jetzt nur etwas gelesen 
und gespielt?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Wieso das?
> Du kannst in C/C++ Zeiger vergleichen, oder Werte.
> Natürlich können zwei Zeiger unterschiedlich sein, aber trotzdem auf
> Elemente mit gleichem Wert verweisen.

Und genau das ist hier auch das (vermeintliche) Problem bei den 
merkwürdig Anmutenden Beispielen, ich wollte nur Zeigen, dass man in C 
genauso "unlogische" Probleme konstruieren kann.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> So ich habe mal ein Beispiel in C zusammengehackt, welches das gleiche
> "Problem" hat:[c]#include <stdio.h>

> Also ist C genauso unlogisch wie Java ;-)


Nö.
Denn dieses Beispiel hast du extra so zurecht gemacht. Das ist nichts 
was dir vom System so vorgesetzt wird, ob du willst oder nicht.

Was natürlich nicht heißt, dass C keine Ecken und Kanten und 
Merkwürdigkeiten hat.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Klaus Wachtler schrieb:
> Das Unlogische an Java ist, daß man mit demselben == mal den Wert
> vergleicht (bei primitiven Datentypen) und mal die Identität feststellt,

> Ebenso wie mal CBV und mal CBR bei Parameterübergabe, je nach Typ.

Wie ich weiter oben schrieb: Betrachte die Java-Objektvariablen einfach
als Pointer (implementierungstechnisch sind sie das ja auch), dann lösen
sich diese Widersprüche in Wohlgefallen auf.

von UR-Schmitt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Denn dieses Beispiel hast du extra so zurecht gemacht. Das ist nichts
> was dir vom System so vorgesetzt wird, ob du willst oder nicht.

In Java setzt dir das System auch nichts vor. Es liegt an dir == für 
primitive Typen und die euqals bzw. compare Methode für Objekte zu 
benutzen. Java ist hier eher konsequenter als C(++) das dir alle 
möglichen Verwirrungen incl operator overloading zulässt.

Einige Ausnahme: Autoboxing.

von Karl H. (kbuchegg)


Lesenswert?

Yalu X. schrieb:
> Klaus Wachtler schrieb:
>> Das Unlogische an Java ist, daß man mit demselben == mal den Wert
>> vergleicht (bei primitiven Datentypen) und mal die Identität feststellt,
>
>> Ebenso wie mal CBV und mal CBR bei Parameterübergabe, je nach Typ.
>
> Wie ich weiter oben schrieb: Betrachte die Java-Objektvariablen einfach
> als Pointer (implementierungstechnisch sind sie das ja auch), dann lösen
> sich diese Widersprüche in Wohlgefallen auf.

Yalu, das ist (denke ich) den meisten schon klar. Und zumindest mir 
gehts da gar nicht mehr drum.

Was mir missfällt ist folgendes.
Angenommen ich habe eine Funktion (Java Syntax Fehler jetzt bitte zu 
entschuldigen)

void foo( int i, int j )
{
  if( i == j )
    mach was
  else
    mach was anderes
}

dann hat die eine klare Semantik. Ändere ich jetzt das int um auf 
Integer

void foo( Integer i, Integer j )
{
  if( i == j )
    mach was
  else
    mach was anderes
}

dann ändert sich die Semantik (== macht bei Integer was anderes als bei 
int). Und wenn ich das nicht bedenke oder sehe, dann hab ich einen 
schwerwiegenden Fehler eingebaut durch eine eigentlich auf den ersten 
Blick harmlose Modifikation. (Integer sei jetzt Synonym für andere 
Klassentypen).

In C++ ist das nicht so. == ist immer ein Wertevergleich. Und wenn meine 
Variablen Pointer sind, dann vergleiche ich immer noch Werte, nämlich 
die in den Pointer Variablen gespeicherten Adressen (sind ja auch 'nur' 
Werte). C++ macht mir aus

    i == j

kein
    &i == &j

abhängig davon, ob i,j primitive Datentypen sind oder ausgewachsene 
Klassen. Und scheinbar sehe nicht nur ich das als unlogisch an.

Ich hätte es logischer empfunden, wenn == immer einen Wertevergleich 
macht und es im Falle von Klassen dann eben eine spezielle Funktion 
gibt, die aufgerufen wird und den Wertevergleich macht. Dann hätte man 
auch gleich die Problematik "Was macht man mit < <= >= >" auch gleich 
unter Dach und Fach - oder gibts da bei Klassen was? Konnte auf die 
Schnelle nichts finden.) Und um festzustellen, ob 2 Objekte identisch 
sind, gibt es dann eben eine isIdent() Member Funktion, die das zu 
bewerkstelligen hat.

Aber egal. Die Dinge sind, wie sie sind.

von UR-Schmitt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> In C++ ist das nicht so. == ist immer ein Wertevergleich. Und wenn meine
> Variablen Pointer sind, dann vergleiche ich immer noch Werte, nämlich
> die in den Pointer Variablen gespeicherten Adressen (sind ja auch 'nur'
> Werte). C++ macht mir aus
>
>     i == j
>
> kein
>     &i == &j

Macht dir Java auch nicht.
Was dich stört ist daß bei Objekten eben implizit eine Adresse auf ein 
Objekt übergeben wird, man muss primitive Typen und Objekte eben 
wirklich konsequent unterscheiden.
Wenn ich nur daran denke was ich früher an wildem Unsinn mit Operator 
Overloading in C++ gesehen habe, dann ist das in Java aber nur ein 
klitzkleines Problem.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl Heinz Buchegger schrieb:
> In C++ ist das nicht so. == ist immer ein Wertevergleich.

So? Und was ist mit
1
int a[3] = {1, 2, 3};
2
int b[3] = {1, 2, 3};
3
4
...
5
  if(a == b)
6
    ...

Überall, wo ein Array-Name als R-Value (und nicht als Operand von
sizeof) auftaucht, wird er wie ein Pointer auf das erste Array-Element
behandelt. Java geht einen Schritt weiter und tut das, was C[++] mit
Arrays macht, mit allen zusammengesetzten Datentypen (wobei in Java
auch Arrays Objekte sind, so dass sich die Unterscheidung zwischen Array
und Objekt ohnehin erübrigt). Das ist in meinen Augen konsistenter.

> Und wenn meine Variablen Pointer sind, dann vergleiche ich immer noch
> Werte, nämlich die in den Pointer Variablen gespeicherten Adressen
> (sind ja auch 'nur' Werte).

Das macht doch Java ebenso (vorausgesetzt man betrachtet Objektvariablen
als Pointer).

von Karl H. (kbuchegg)


Lesenswert?

UR-Schmitt schrieb:
> Karl Heinz Buchegger schrieb:
>> In C++ ist das nicht so. == ist immer ein Wertevergleich. Und wenn meine
>> Variablen Pointer sind, dann vergleiche ich immer noch Werte, nämlich
>> die in den Pointer Variablen gespeicherten Adressen (sind ja auch 'nur'
>> Werte). C++ macht mir aus
>>
>>     i == j
>>
>> kein
>>     &i == &j
>
> Macht dir Java auch nicht.

Schon klar. Weil es die & Operation dort nicht gibt. Aber genau darauf 
läuft es hinaus. Da Wertevergleich - dort Adressenvergleich.


> Wenn ich nur daran denke was ich früher an wildem Unsinn mit Operator
> Overloading in C++ gesehen habe,

Ooooohhhh, jaaaaaa

Da kann man sich ganz schnell in die Probleme rein-katapultieren :-)

> dann ist das in Java aber nur ein
> klitzkleines Problem.

Muss ich dir glauben und glaub ich dir auch.

von UR-Schmitt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ooooohhhh, jaaaaaa
>
> Da kann man sich ganz schnell in die Probleme rein-katapultieren :-)

:-)
Schönen Feierabend

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> "Was macht man mit < <= >= >"

Dafür gibt es das Interface Comparable welches, oh Wunder :-) von 
Integer implementiert wird.

Karl Heinz Buchegger schrieb:
> dann ändert sich die Semantik
Es ändert sich insbesondere die Semantik von der ganzen Funktion, was 
machst du wenn jetzt eines der Argumente null ist? Ich kann mir nicht 
vorstellen, dass in C++ das nicht auch auf einen NullPointerAccess 
hinauslaufen würde, die Änderung ist also in jedem Falle nicht ohne 
Anpassen/Nachdenken "einfach so" anpassbar.
Wenn man dann seine IDE richtig einstellt wird man auch eine passende 
Warnung erhalten.

von Karl H. (kbuchegg)


Lesenswert?

Yalu X. schrieb:
> Karl Heinz Buchegger schrieb:
>> In C++ ist das nicht so. == ist immer ein Wertevergleich.
>
> So? Und was ist mit
>
>
1
> int a[3] = {1, 2, 3};
2
> int b[3] = {1, 2, 3};
3
> 
4
> ...
5
>   if(a == b)
6
>     ...
7
>

Tuschee.
An Arrays hab ich jetzt nicht gedacht. Punkt für dich. Arrays sind 
sowohl in C als auch in C++ Bastarde.

Aber spätestens bei

  std::vector<int> a;
  std::vectot<int> b;

  if( a == b )

sind wir wieder auf Wertevergleichen. (Und ja: IN C++ gibts auch ein 
std::array, welches sich 'korrekt' verhält)

> Es ändert sich insbesondere die Semantik von der ganzen Funktion,
> was machst du wenn jetzt eines der Argumente null ist? Ich kann mir
> nicht vorstellen, dass in C++ das nicht auch auf einen
> NullPointerAccess hinauslaufen würde

Ändere ich

void foo( int i, int j )
{
  if( i == j )
    mach was
  else
    mach was anderes
}

auf

void foo( std::string i, std::string j )
{
  if( i == j )
    mach was
  else
    mach was anderes
}

ändert sich an der Semantik gar nichts. Noch nicht mal ein

void foo( std::string& i, std::string& j )
{
  if( i == j )
    mach was
  else
    mach was anderes
}

muss mir (an dieser Stelle) Kopfzerbrechen machen, weil eine Referenz 
immer auf ein existierendes Objekt zeigen muss. Wenn hier also ein null 
Pointer im Spiel ist, dann hat der Aufrufer einen Fehler gemacht. (Was 
nicht heißt das eine entsprechende Überprüfung nicht sinnvoll wäre. Aber 
in C+ ist es auf legalem Weg nicht möglich eine Referenz auf ein 
NULL-Objekt zu erzeugen)
Erst wenn ich auf

void foo( std::string * i, std::string * j )
{
  if( *i == *j )
    mach was
  else
    mach was anderes
}

gehe, muss ich mir in der Funktion Gedanken über mögliche null Pointer 
machen. Da hab ich aber nicht einfach nur einen primtiven Typ gegen 
einen Klassentyp ausgetauscht, sondern durch den Pointer der ganzen 
Funktion eine ganz andere Wendung gegeben.
(Ja ich weiß schon. du wirst jetzt sagen, dass das ja genau das ist was 
in Java 'under the hood' gemacht wird. Und ja, ich geb dir ja auch 
recht. Nur muss ich in C++ da schon ein wenig mehr machen als nur 1 Wort 
gegen ein anderes austauschen. C++ macht mir da etwas mehr bewusst, dass 
hier etwas komplett anderes abgeht)

Wichtig ist sowas zb bei Templates, bei denen es fatal wäre, wenn ein == 
in einem Template je nachdem ob man das für einen primtiven Typ oder 
einen Klassentyp instaziiert sich unterschiedlich verhält.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> muss mir (an dieser Stelle) Kopfzerbrechen machen, weil eine Referenz
> immer auf ein existierendes Objekt zeigen muss

Wie gesagt, in Java gilt dies nicht! Wenn dann müßtest du dein Beispiel 
von int, int auf int*, int* ändern und dann hättest du das Problem.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> Karl Heinz Buchegger schrieb:
>> muss mir (an dieser Stelle) Kopfzerbrechen machen, weil eine Referenz
>> immer auf ein existierendes Objekt zeigen muss
>
> Wie gesagt, in Java gilt dies nicht! Wenn dann müßtest du dein Beispiel
> von int, int auf int*, int* ändern und dann hättest du das Problem.


Yep.
Und da ist dann eben der Unterschied der, dass mir C bzw. C++ hier etwas 
mehr bewusst macht, dass da plötzlich etwas anderes abgeht. Mit dem 
Austausch eines Datentyps durch einen Pointer-Typ ist es nicht getan. Da 
fallen Änderungen an, auf die mich der COmpiler bei Nichtbeachtung 
aufmerksam macht (zb. das sich beim Aufrufer etwas ändern muss)

Aber ich klink mich jetzt aus.
Ich denke die Standpunkte sind klar. Da jetzt großartig diskutieren 
bringt auch nichts, denn wir bestimmen nicht die Sprachrichtung.
Danke für ein paar Einsichten in Java.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Mit dem Austausch eines Datentyps durch einen Pointer-Typ
> ist es nicht getan
Das ist doch bei Java ebenso...

Karl Heinz Buchegger schrieb:
> auf die mich der COmpiler bei Nichtbeachtung
> aufmerksam macht (zb. das sich beim Aufrufer etwas ändern muss)
Hier dito, es gibt wie gesagt den einen Spezialfall, dass dann der 
Aufrufer nichts ändern braucht, da autoboxing geschieht, aber ob der 
Compiler das tut oder nicht, entbindet dich in keinster Weise davon zu 
prüfen ob deine Änderung der Funktionsparameter nicht auch eine Änderung 
der Funktion zur Folge hat.

Wenn das Wirklich eine Funktion ist, welche nicht von den Argumenten 
abhängt sondern nur davon ob diese gleichwertig sind, könnte man doch 
gleich auf equals oder auf Compareable gehen, und könnte dann sogar 
beliebige Eingaben erlauben. Die ganze "Problematik" ist überhaupt gar 
keine, außer das sich Leute berufen fühlen daraus imaginäre Probleme zu 
konstruieren.

von Rolf Magnus (Gast)


Lesenswert?

Läubi .. schrieb:
> Rolf Magnus schrieb:
>> Naja, bei C++ gibt es eben eine genaue Trennung,
>> welche Operationen sich auf den Zeiger und welche
>> auf das Objekt auswirkt
> Gibt es bei Java auch,

Allerdings reicht es da nicht, nur die Operation zu betrachten, sondern 
es hängt auch noch vom Typ ab. Das war es, was ich damit meinte.

> nur weil man sie nicht kennt, oder sie zufällig gleich der ist welche man
> von andere Seite her kennt heist nicht das es unlogisch ist.

Und nur weil sie logisch ist, muß sie nicht gut sein.

> Rolf Magnus schrieb:
>> Wie ist das eigentlich bei den primitiven Typen? Werden bei dem
>> folgenden auch Adressen vergleichen, oder ist es da dann wieder anders?
> Es ist nicht "wieder" anders, sondern es wird die auf int definierte
> Operation == durchgeführt. Diese ist aber nicht die gleiche wie für
> Object und auch nicht die gleiche wie z.B. für boolean.

Also ist sie doch eine andere als für Objekte, und genau das halte ich 
für keine gute Idee. Natürlich ist es nicht unlogisch, aber unintuitiv.
Rein interessehalber: Was macht diese Operation denn für boolean, wenn 
nicht die Werte vergleichen?

> Rolf Magnus schrieb:
>> Schon hier kommt bei mir die Frage auf, warum ich überhaupt eine Klasse
>> statt eines int brauchen könnte,
> Z.B. analog wie in C++, weil eine int variable nicht 'null' sein kann
> oder eine Rückgabe einer Funktion die int zurückgibt nicht 'null' sein
> kann.

Ok. Ich dachte, die Gründe wären etwas weitreichender.

> Rolf Magnus schrieb:
>> Das Argument leuchtet mir nicht ein
> Variable != Objekt/Wert. Schreib doch mal in C rein 7 = 5, da wird sich
> der Compiler auch beschweren, da man dem "Wert" 7 keinen neue Bedeutung
> zuweisen kann, das hat man halt versucht nachzubauen, insbesondere da es
> in Java kein 'const' gibt.

Du willst damit doch nicht etwa sagen, daß es ein wesentlicher 
Anwendungsfall von Integer ist, int-Konstanten zu definieren?

> Rolf Magnus schrieb:
>> Dafür einen extra Typ definieren zu müssen finde ich aber
>> doch etwas umständlich
> Was ist den "Dafür", der TE schreibt ja nicht mal wozu er das haben
> will, diese Operation "Speicherzelle eines Int" an eine Funktion zu
> übergeben gibt es schlich nicht, und man benötigt sie auch in der Regel
> nicht.

Wo steht denn was von Speicherzellen? Er will einfach nur einen int 
modifizieren, den er per Referenz in die Funktion reinbekommt, so wie 
man das mit Objekten auch ständig macht. Das klingt mir nicht so weit 
hergeholt. In C++ übergebe ich halt eine Referenz auf den int, und bei 
einem Objekt übergebe ich eine Referenz auf das Objekt, und fertig.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf Magnus schrieb:
>> Rolf Magnus schrieb:
>>> Schon hier kommt bei mir die Frage auf, warum ich überhaupt eine Klasse
>>> statt eines int brauchen könnte,
>> Z.B. analog wie in C++, weil eine int variable nicht 'null' sein kann
>> oder eine Rückgabe einer Funktion die int zurückgibt nicht 'null' sein
>> kann.
>
> Ok. Ich dachte, die Gründe wären etwas weitreichender.

Ich glaube, der Hauptgrund für die Existenz der Integer-Klasse ist die
Vervollkommnung des Prinzips "everything is an object". Das hat nicht
nur ästhetische, sondern vor allem auch praktische Vorteile:

In Java sind alle Klassen direkt oder indirekt von der Klasse "Object"
abgeleitet. Man kann sehr allgemeingehaltene Klassen und Methoden
schreiben, wenn man die verwendeten Membervariablen bzw. Methodenargu-
mente als Object deklariert. M.W. waren in früheren Java-Versionen die
Container-Datentypen (Listen, Bäume usw.) genau so realisiert. Da die
Werte primitiver Datentypen aber keine Objekte sind, benötigt man
Wrapper-Klassen, um auch sie in gleicher Weise verwenden zu können.

Mit der Einführung von Generics¹ dürfte sich der Bedarf nach Objekten
der Klasse Object etwas gelegt haben. Trotzdem kann es manchmal sinnvoll
sein, Container anzulegen, bei denen die einzelnen Elemente unterschied-
lichen Typs sein können. Das geht aber nur, wenn die einzelnen Typen
eine gemeinsame Basisklasse haben, und die ist eben in vielen Fällen
Object. Sollen nur numerische Werte gespeichert werden, wäre die gemein-
same Basisklasse stattdessen Number, von denen bspw. Integer, Double,
und BigInteger abgeleitet sind.

Ich verstehe allerdings nicht ganz, warum man überhaupt die primitiven
Datentypen von C++ übernommen hat. Der Effizienzgewinn sollte eigentlich
kein Grund gewesen sein, denn es wäre in einer stark typisierten Sprache
wie Java sicher möglich gewesen, die gleiche Effizienz durch eine Son-
derbehandlung der Klassen Integer, Double usw. vonseiten des Compilers
zu erreichen. Aber so tief stecke ich in dem Java-Gedöns nicht drin, um
das sicher beurteilen zu können :)

————————————
¹) Diese entsprechen in etwa den Templates in C++.

von Udo S. (urschmitt)


Lesenswert?

Yalu X. schrieb:
> Ich glaube, der Hauptgrund für die Existenz der Integer-Klasse ist die
> Vervollkommnung des Prinzips "everything is an object".

Der Grund ist doch einfach, daß man ints und andere primitive Typen so 
nicht in den Klassen wie dem Collection Framework benutzen könnte.

Yalu X. schrieb:
> Ich verstehe allerdings nicht ganz, warum man überhaupt die primitiven
> Datentypen von C++ übernommen hat. Der Effizienzgewinn sollte eigentlich
> kein Grund gewesen sein,

Na ja wenn du sehr rechenintensive Anwendungen mit vielen char oder int 
Vergleichen / sortierungen etc hast dann dürfte sich das massiv 
bemerkbar machen. Man sollte nicht vergessen wie alt Java inzwischen 
schon ist und wie langsam damals die Rechner noch waren.
Performance war der große Kritikpunkt aller objektorientierten Sprachen 
und einer der Gründe daß C++ als sehr performante Hybridsprache so viel 
Zuspruch erfahren hat.

Yalu X. schrieb:
> die gleiche Effizienz durch eine Son-
> derbehandlung der Klassen Integer, Double usw. vonseiten des Compilers
> zu erreichen.
Hmm, keine Ahnung ich habe von Compilerbau keine Ahnung, aber trivial 
ist das bestimmt nicht.

Egal, für uns ist Java ein riesengroßer Segen, alle Kritiker sollen mir 
mal das C++ Programm zeigen, das relativ performant in mehreren 
unterschiedlichen Application Server lauffähig ist und mit EINER 
Auslieferung für alle Unix Derivate (incl AIX und Solaris), für Windows 
und (mit Tricks) sogar auf dem Host läuft, und eine leistungsfähige 
Datenbankanbindung an Oracle, MSSQLServer oder DB/2 hat. Wenn nötig 
sogar an unterschiedliche DBMS gleichzeitig!
Zusätzlich war es relativ leicht eine MQ Anbindung zu bekommen (auch 
unabhängig vom Betriebssystem).
In unseren C Programmen heisst das etwa 20 unterschiedliche Builds 
durchzuführen, jede Version/Patch in den 20 Auslieferungen vorzuhalten, 
die Builds zu testen usw. usw. Und dabei sind dann noch nicht mal alle 
Kombinationen vorrätig und kein MQ.

Schönen Abend :-)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Ok. Ich dachte, die Gründe wären etwas weitreichender.
Yalu X. schrieb:
> Ich glaube, der Hauptgrund für die Existenz der Integer-Klasse ist die
> Vervollkommnung des Prinzips "everything is an object".
Udo Schmitt schrieb:
> Der Grund ist doch einfach, daß man ints und andere primitive Typen so
> nicht in den Klassen wie dem Collection Framework benutzen könnte.
Es gibt natürlich noch sehr viel mehr Gründe, ich denke eine 
vollständige Liste wird man nicht aufstellen könne, z.B. kann man sehr 
schön Algorithmen auf der abstrakten Klasse Number aufbauen, der kann 
man dann shorts/ints/floats/double/BigInt/BigDecimal/... übergeben.

Yalu X. schrieb:
> Trotzdem kann es manchmal sinnvoll
> sein, Container anzulegen, bei denen die einzelnen Elemente unterschied-
> lichen Typs sein können.

Ja z.B. eine Liste von Numbers ;-) aber gerade für Generics benötigt 
man halt diese "Objektprimitiven"...

Yalu X. schrieb:
> Ich verstehe allerdings nicht ganz, warum man überhaupt
> die primitiven Datentypen von C++ übernommen hat
Ob man die von C++ übernommen hat sei mal dahingestellt, intern ist es 
halt so, dass die VM Operationen auf int/long und float/double 
definiert. Ich kann mir vorstellen das es einmal "Gewöhnung" war, jeder 
"kennt" halt so Basistypen, andererseits hat man halt so ein bischen ein 
Henne/Ei Problem:
Woraus soll das "Urobjekt" für Zahlen bestehen wenn es nichts gibt außer 
Object? Klar könnte man es wie bei String machen, aber selbst String 
baut schon auf den "primitiven" byte und char auf...

Yalu X. schrieb:
> denn es wäre in einer stark typisierten Sprache
> wie Java sicher möglich gewesen, die gleiche Effizienz
> durch eine Sonderbehandlung der Klassen Integer, Double
> usw. vonseiten des Compilers zu erreichen
Jein, sicher wäre das "irgendwie" möglich gewesen, aber ein Objekt ist 
immer mit etwas mehr Aufwand verbunden, besonders die Stackoperationen 
würden dann auf der Abstrakten(!) VM sehr viel komplexer zu beschreiben 
sein, da man sehr viele Sonderfälle hätte.

Wer sich das genauer ansehen will kann sich entweder obiges Dokument zu 
Gemüt führen, oder mal in die doc32049.pdf von ATMEL reinschnuppern, da 
wird das JVM Modul des AVR32 AP7000 beschrieben, ein teil der JVM 
instruktionen wird direkt von der CPU ausgeführt, ein teil durch 
Traps/Eventhandler... und das sind z.B. jene welche sich um die 
Erzeugung von Objekten drehen.
Eine (vereinfachte) JVM in Hardware kann man z.B. bei Tanenbaum 
bewundern: http://en.wikipedia.org/wiki/IJVM die hab ich mal in VHDL 
nachgebaut, da weiß man dann zu schätzen was der arme PC tagtäglich 
leisten muss ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.