Вы сбиты с толку, потому что ваша аналогия неверна. В Java нет такой вещи, как «объект аргумента», потому что сами «объекты» не являются значениями в Java (в Java нет «типов объектов»). Единственные типы в Java - это примитивные типы и ссылочные типы, где «ссылки» - это указатели на объекты. Таким образом, в Java у вас могут быть только указатели на объекты в качестве значения переменной или параметра, и вы имеете дело только с объектами через указатели на объекты.
«вы не можете изменить место, куда указывает этот указатель» - это следствие передачи по значению. Java всегда передается по значению, что означает, что присвоение параметру не может изменить значение переданной переменной. Помните, что переменные могут быть только примитивного или ссылочного типа. Здесь вы говорите о ссылочном типе. Таким образом, «значением» переменной ссылочного типа является ссылка (указатель на объект), то есть адрес объекта, на который она указывает. Следовательно, вы не можете изменить значение, что означает, что вы не можете изменить место, куда указывает указатель.
Например, в Java у вас может быть что-то вроде этого:
public static void reassign(String a) {
a = new String("efgh");
}
public static void main(String[] args) {
String x = "abcd";
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
reassign(x);
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
}
Здесь x
в main
- указатель на объект. a
в reassign
также является указателем на объект. Присвоение параметру указателя a
в reassign
не влияет на переданную переменную указателя x
(т. Е. Не влияет на то, куда указывает указатель), потому что он передается по значению.
Эквивалент приведенного выше кода на C ++ будет таким:
void reassign(string *a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
return 0;
}
В дополнение к передаче по значению, показанной выше, C ++ также имеет передачу по ссылке, где присвоение параметру имеет тот же эффект, что и присвоение переданной переменной в вызывающей области. Вот то же самое, что и выше, но с передачей по ссылке:
void reassign(string *&a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x8673008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is efgh at 0x8673030
return 0;
}
Обратите внимание, что ни в одном из приведенных здесь случаев мы не изменили объект, на который указывает. Мы просто создали новый объект и попытались изменить указатель, чтобы он указывал на этот объект. Старый объект остался без изменений. Возможность изменения объекта - это независимая и ортогональная проблема, по сравнению с передачей по значению и передачей по ссылке, поэтому мы не будем вдаваться в подробности здесь.
person
newacct
schedule
25.05.2015
reassign()
просто создает новую строку в том же месте памяти, на которое ссылаетсяa
. Если вы хотите изменить адрес, вам нужно будет передать либо ссылку на указатель, либо указатель на указатель. - person Austin Brunkhorst   schedule 20.05.2015"string mystr = string("newstring")"
не то же самое, что"string mystr = *(new string("newstring"))"
с точки зрения динамического распределения памяти? - person ladiesman   schedule 20.05.2015