Wenn wir eine grobe Analogie zwischen C und Assembler herstellen wollen:
void Main()
{
// stack memory address of message is 0x8001. memory address of Hello is 0x0001.
string message = "Hello";
// assembly equivalent of: message = "Hello";
// [0x8001] = 0x0001
// message's stack memory address
printf("%d", &message); // 0x8001
printf("%d", message); // memory pointed to of message(0x8001): 0x0001
PassStringByValue(message); // pass the pointer pointed to of message. 0x0001, not 0x8001
printf("%d", message); // memory pointed to of message(0x8001): 0x0001. still the same
// message's stack memory address doesn't change
printf("%d", &message); // 0x8001
}
void PassStringByValue(string foo)
{
printf("%d", &foo); // &foo contains foo's *stack* address (0x4001)
// foo(0x4001) contains the memory pointed to of message, 0x0001
printf("%d", foo); // 0x0001
// World is in memory address 0x0002
foo = "World"; // on foo's memory address (0x4001), change the memory it pointed to, 0x0002
// assembly equivalent of: foo = "World":
// [0x4001] = 0x0002
// print the new memory pointed by foo
printf("%d", foo); // 0x0002
// Conclusion: Not in any way 0x8001 was involved in this function. Hence you cannot change the Main's message value.
// foo = "World" is same as [0x4001] = 0x0002
}
void Main()
{
// stack memory address of message is 0x8001. memory address of Hello is 0x0001.
string message = "Hello";
// assembly equivalent of: message = "Hello";
// [0x8001] = 0x0001
// message's stack memory address
printf("%d", &message); // 0x8001
printf("%d", message); // memory pointed to of message(0x8001): 0x0001
PassStringByRef(ref message); // pass the stack memory address of message. 0x8001, not 0x0001
printf("%d", message); // memory pointed to of message(0x8001): 0x0002. was changed
// message's stack memory address doesn't change
printf("%d", &message); // 0x8001
}
void PassStringByRef(ref string foo)
{
printf("%d", &foo); // &foo contains foo's *stack* address (0x4001)
// foo(0x4001) contains the address of message(0x8001)
printf("%d", foo); // 0x8001
// World is in memory address 0x0002
foo = "World"; // on message's memory address (0x8001), change the memory it pointed to, 0x0002
// assembly equivalent of: foo = "World":
// [0x8001] = 0x0002;
// print the new memory pointed to of message
printf("%d", foo); // 0x0002
// Conclusion: 0x8001 was involved in this function. Hence you can change the Main's message value.
// foo = "World" is same as [0x8001] = 0x0002
}
Ein möglicher Grund, warum in Java alles als Wert übergeben wird, ist, dass die Sprachdesigner die Sprache vereinfachen und alles in OOP-Manier machen wollen.
Sie würden lieber einen Integer-Swapper mit Objekten entwerfen, als dass sie eine erstklassige Unterstützung für die Übergabe von By-Referenzen bereitstellen, dasselbe gilt für Delegate (Gosling fühlt sich unwohl mit Zeigern auf Funktionen, er würde diese Funktionalität lieber in Objekte packen) und Enum.
Sie vereinfachen die Sprache zu sehr (alles ist ein Objekt), was dazu führt, dass die meisten Sprachkonstrukte nicht erstklassig unterstützt werden, z. B. Referenzübergabe, Delegierte, Enum, Eigenschaften.
0 Stimmen
Ich bin mir nicht ganz sicher, was Sie damit sagen wollen. Bitte klären Sie es ein wenig?
0 Stimmen
Der vorherige Titel war nicht gut, denn es wäre unmöglich, den Inhalt Ihrer Frage über den Titel zu suchen.
0 Stimmen
Kein Problem, dieser Titel macht mehr Sinn :)
1 Stimmen
Stellen Sie sich Java-Referenzvariablen als Zeiger vor und alles wird klar ;)
2 Stimmen
Siehe auch stackoverflow.com/questions/2027/