Чтобы добавить к этому; Это может произойти, если вы не приложите свой набор данных. Просто потратил полчаса, выяснив это также.
Cheers
Java всегда передача значением . К сожалению, когда мы передаем значение объекта, мы передаем ссылка к нему. Это сбивает с толку новичков.
Это идет как это:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
В примере выше aDog.getName()
все еще возвратится "Max"
. Значение aDog
в main
не изменяется в функции foo
с Dog
"Fifi"
, когда ссылка на объект передается значением. Если бы это было передано ссылкой, то aDog.getName()
в [1 110] возвратился бы "Fifi"
после вызова к [1 112].
Аналогично:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
// but it is still the same dog:
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
В вышеупомянутом примере, Fifi
имя собаки после вызова к [1 114], потому что имя объекта было определено в foo(...)
. Любые операции, который foo
работает на [1 117], таковы, что во всех практических целях они выполняются на [1 118], но не возможно изменить значение переменной aDog
самой.
В основном переприсвоение Параметров объекта не влияет на аргумент, например,
private void foo(Object bar) {
bar = null;
}
public static void main(String[] args) {
String baz = "Hah!";
foo(baz);
System.out.println(baz);
}
распечатает "Hah!"
вместо null
. Причина это работает, состоит в том, потому что bar
копия значения baz
, который является просто ссылкой на "Hah!"
. Если бы это была сама фактическая ссылка, то foo
переопределил бы baz
к null
.
Основная проблема - то, что ссылка Word в выражении "передача ссылкой" означает что-то совершенно другое от обычного значения ссылки Word в Java.
Обычно в ссылке Java означает ссылка на объект . Но технические термины передача ссылкой/значением из теории языка программирования говорит о ссылка на элемент памяти, содержащий переменную , который является чем-то совершенно другим.
Java передает ссылки на объекты значением.
Только для проявления контраста сравните следующий C++ и Java отрывки:
В C++: Примечание: Плохой код - утечки памяти! , Но это демонстрирует точку.
void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
val = 7; // Modifies the copy
ref = 7; // Modifies the original variable
obj.SetName("obj"); // Modifies the copy of Dog passed
objRef.SetName("objRef"); // Modifies the original Dog passed
objPtr->SetName("objPtr"); // Modifies the original Dog pointed to
// by the copy of the pointer passed.
objPtr = new Dog("newObjPtr"); // Modifies the copy of the pointer,
// leaving the original object alone.
objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to
// by the original pointer passed.
objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}
int main()
{
int a = 0;
int b = 0;
Dog d0 = Dog("d0");
Dog d1 = Dog("d1");
Dog *d2 = new Dog("d2");
Dog *d3 = new Dog("d3");
cppMethod(a, b, d0, d1, d2, d3);
// a is still set to 0
// b is now set to 7
// d0 still have name "d0"
// d1 now has name "objRef"
// d2 now has name "objPtr"
// d3 now has name "newObjPtrRef"
}
В Java,
public static void javaMethod(int val, Dog objPtr)
{
val = 7; // Modifies the copy
objPtr.SetName("objPtr") // Modifies the original Dog pointed to
// by the copy of the pointer passed.
objPtr = new Dog("newObjPtr"); // Modifies the copy of the pointer,
// leaving the original object alone.
}
public static void main()
{
int a = 0;
Dog d0 = new Dog("d0");
javaMethod(a, d0);
// a is still set to 0
// d0 now has name "objPtr"
}
Java только имеет два типа передачи: значением для встроенных типов, и значением указателя для типов объектов.
Java передает ссылки значением.
, Таким образом, Вы не можете изменить ссылку, которая передается в.
Java всегда является передачей значением, без исключений, когда-либо .
Поэтому как получается, что кто-либо может быть вообще смущен этим и полагать, что Java является передачей ссылкой, или думают, что у них есть пример Java, действующего как передача ссылкой? Ключевой пункт - то, что Java никогда не обеспечивает прямой доступ к значениям сами объекты , в никакой обстоятельства. Единственный доступ к объектам через ссылка к тому объекту. Поскольку объекты Java всегда , получил доступ через ссылку, а не непосредственно, распространено говорить о полях и переменных и аргументы метода как являющийся объекты , когда педантично они - [только 1 110] ссылки на объекты . беспорядок останавливает от этого (строго говоря, неправильный) изменение в номенклатуре.
Так, при вызове метода
int
, long
, и т.д.), передача значением фактическое значение из примитива (например, 3). Поэтому, если Вы имеете doSomething(foo)
и public void doSomething(Foo foo) { .. }
, два Foos скопировали ссылки что точка к тем же объектам.
Естественно, передающий значением ссылка на объект смотрит очень как (и неотличимо на практике от), передача объекта ссылкой.
Я просто заметил, что Вы сослались моя статья .
, Спецификация Java говорит, что все в Java - передача значением. Нет такой вещи как "передача ссылкой" в Java.
ключ к пониманию это - то, что что-то как [1 145]
Dog myDog;
не Собака; это на самом деле указатель Собаке.
то, Что это означает, когда Вы имеете
Dog myDog = new Dog("Rover");
foo(myDog);
, Вы чрезвычайно передающие адрес из созданных Dog
объект к foo
метод.
(я говорю по существу, потому что указатели Java не являются прямыми адресами, но является самым легким думать о них тот путь)
предположим эти Dog
, объект находится в адресе памяти 42. Это означает, что мы передаем 42 методу.
, если Метод был определен как [1 151]
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
, позволяют нам посмотреть на то, что происходит.
someDog
устанавливается на значение 42 someDog
, сопровождается к Dog
, это указывает на (эти Dog
объект в адресе 42) Dog
(тот в адресе 42) попросился изменить его имя на MaxDog
создается. Скажем, он в адресе 74 someDog
74 Dog
, это указывает на (эти Dog
объект в адресе 74) Dog
(тот в адресе 74) попросился изменить его имя на RowlfТеперь, давайте думать о том, что происходит вне метода:
Сделал myDog
изменение?
существует ключ.
Учет того факта, который myDog
указатель , и не фактическое Dog
, ответ, НЕТ. myDog
все еще имеет значение 42; это все еще указывает на оригинал Dog
(но обратите внимание, что из-за строки "AAA", его именем является теперь "Max" - все еще та же Собака; myDog
значение не изменилось.)
Это совершенно допустимо к [1 131], следуют адрес и изменяют то, что в конце его; это не заменяет переменную, как бы то ни было.
Java работает точно как C. Можно присвоить указатель, передать указатель на метод, следовать за указателем в методе и изменить данные, на которые указали. Однако Вы не можете измениться, где тот указатель указывает.
В C++, Ada, Паскале и других языках, которые поддерживают передачу ссылкой, можно на самом деле заменить переменную, которая была передана.
, Если бы Java имел семантику передачи ссылкой, foo
метод, мы определили выше, изменился бы, где myDog
указывал, когда это присвоилось someDog
на строке BBB.
Думают о параметрах ссылки, как являющихся псевдонимами для переменной, переданной в. Когда тот псевдоним присвоен, так переменная, которая была передана в.
Вы никогда не можете передавать ссылкой в Java, и один из путей, который очевиден, - когда Вы хотите возвратить больше чем одно значение из вызова метода. Рассмотрите следующий бит кода в C++:
void getValues(int& arg1, int& arg2) {
arg1 = 1;
arg2 = 2;
}
void caller() {
int x;
int y;
getValues(x, y);
cout << "Result: " << x << " " << y << endl;
}
Иногда Вы хотите использовать тот же шаблон в Java, но Вы не можете; по крайней мере, не непосредственно. Вместо этого Вы могли сделать что-то вроде этого:
void getValues(int[] arg1, int[] arg2) {
arg1[0] = 1;
arg2[0] = 2;
}
void caller() {
int[] x = new int[1];
int[] y = new int[1];
getValues(x, y);
System.out.println("Result: " + x[0] + " " + y[0]);
}
, Как был объяснен в предыдущих ответах, в Java, Вы передаете указатель на массив как значение в getValues
. Это достаточно, потому что метод тогда изменяет элемент массива, и условно Вы ожидаете, что элемент 0 будет содержать возвращаемое значение. Очевидно, можно сделать это другими способами, такими как структурирование кода, таким образом, это не необходимо, или построение класса, который может содержать возвращаемое значение или позволить ему быть установленным. Но простой шаблон, доступный Вам в C++ выше, не доступен в Java.
Различие, или возможно просто способ, которым я помню, когда я раньше создавался то же впечатление как исходный плакат, является этим: Java всегда является передачей значением. Все объекты (в Java, чем-либо за исключением примитивов) в Java являются ссылками. Эти ссылки передаются значением.
Короче говоря, объекты Java имеют некоторые очень специфические свойства.
В целом, Java имеет типы примитивов (int
, bool
, char
, double
, и т.д.), которые передаются непосредственно значением. Тогда Java имеет объекты (все, что происходит от java.lang.Object
). Объекты на самом деле всегда обрабатываются через ссылку (ссылка, являющаяся указателем, которого Вы не можете коснуться). Это означает, что в действительности, объекты передаются ссылкой, поскольку ссылки обычно не интересны. Это однако означает, что Вы не можете измениться, на какой объект указывают, когда сама ссылка передается значением.
это звучит странным и сбивающим с толку? Давайте рассмотрим, как передача реализаций C ссылкой и передает значением. В C соглашение по умолчанию является передачей значением. void foo(int x)
передачи интервал значением. void foo(int *x)
функция, которая не хочет int a
, но указатель на интервал: foo(&a)
. Можно было бы использовать это с &
оператор для передачи переменного адреса.
Берут это к C++, и у нас есть ссылки. Ссылки являются в основном (в этом контексте) синтаксическим сахаром, которые скрывают часть указателя уравнения: void foo(int &x)
назван [1 111], где сам компилятор знает, что это - ссылка, и адрес нессылки a
должен быть передан. В Java все переменные, относящиеся к объектам, на самом деле имеют ссылочный тип, в действительности вызывание вызова по ссылке для большинства предназначает и цели без мелкомодульного управления (и сложность) предоставленный, например, C++.
Я создал поток, посвященный подобным вопросам для любой языки программирования здесь .
Java также упоминается . Вот краткое изложение:
Я всегда думаю о нем как о "передаче копией". Это - копия значения быть им примитивный или ссылочный. Если это - примитив, это - копия битов, которые являются значением и если это - Объект, это - копия ссылки.
public class PassByCopy{
public static void changeName(Dog d){
d.name = "Fido";
}
public static void main(String[] args){
Dog d = new Dog("Maxx");
System.out.println("name= "+ d.name);
changeName(d);
System.out.println("name= "+ d.name);
}
}
class Dog{
public String name;
public Dog(String s){
this.name = s;
}
}
вывод java PassByCopy:
имя = имя Maxx
= Fido
Примитивные классы обертки и Строки неизменны, таким образом, любой пример с помощью тех типов не будет работать то же другими типами/объектами.
Поскольку многие люди упомянули его прежде, , Java всегда является передачей значением
, Вот другой пример, который поможет Вам понять различие ( классический пример подкачки ):
public class Test {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = new Integer(3);
System.out.println("Before: a = " + a + ", b = " + b);
swap(a,b);
System.out.println("After: a = " + a + ", b = " + b);
}
public static swap(Integer iA, Integer iB) {
Integer tmp = iA;
iA = iB;
iB = tmp;
}
}
Печать:
Прежде: = 2, b = 3
После: = 2, b = 3
Это происходит, потому что iA и iB являются новыми переменными локальной ссылки, которые имеют то же значение переданных ссылок (они указывают на a и b соответственно). Так, попытка изменить ссылки iA или iB только изменится в локальном объеме а не за пределами этого метода.
Насколько я знаю, Java только знает вызов по значению. Это означает для примитивных типов данных, Вы будете работать с копией, и для объектов Вы будете работать с копией ссылки на объекты. Однако я думаю, что существуют некоторые ловушки; например, это не будет работать:
public static void swap(StringBuffer s1, StringBuffer s2) {
StringBuffer temp = s1;
s1 = s2;
s2 = temp;
}
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("World");
swap(s1, s2);
System.out.println(s1);
System.out.println(s2);
}
Это заполнит Привет Мир и не Мир Привет, потому что в подкачке функционируют, Вы используете копии, которые не оказывают влияния на ссылки в основном. Но если Ваши объекты не неизменны, можно изменить его, например:
public static void appendWorld(StringBuffer s1) {
s1.append(" World");
}
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hello");
appendWorld(s);
System.out.println(s);
}
Это заполнит Привет Мир на командной строке. При изменении StringBuffer в Строку, это произведет просто Привет, потому что Строка неизменна. Например:
public static void appendWorld(String s){
s = s+" World";
}
public static void main(String[] args) {
String s = new String("Hello");
appendWorld(s);
System.out.println(s);
}
Однако Вы могли сделать обертку для Строки как это, которое сделает способным использовать ее со Строками:
class StringWrapper {
public String value;
public StringWrapper(String value) {
this.value = value;
}
}
public static void appendWorld(StringWrapper s){
s.value = s.value +" World";
}
public static void main(String[] args) {
StringWrapper s = new StringWrapper("Hello");
appendWorld(s);
System.out.println(s.value);
}
править: я полагаю, что это - также причина использовать StringBuffer когда дело доходит до "добавления" двух Строк, потому что Вы можете modifie исходный объект, какой u не может с неизменными объектами как Строка.
Несколько исправлений к некоторым постам.
C НЕ поддерживает передачу по ссылке. Это ВСЕГДА передается по значению. C++ поддерживает передачу по ссылке, но не по умолчанию и достаточно опасно.
Неважно, какое значение на Java: примитивное или адрес(грубо) объекта, оно ВСЕГДА передается по значению.
Если объект Java "ведет" себя так, как будто передается по ссылке, то это свойство мутируемости и не имеет абсолютно никакого отношения к передаваемым механизмам.
Не понимаю, почему это так запутанно, возможно, потому, что так много Java "программистов" формально не обучены, а значит, не понимают, что же на самом деле происходит в памяти?
.Немного трудно понять, но Java всегда копирует значение - точка, обычно значение является ссылкой. Поэтому Вы заканчиваете с тем же объектом, не думая об этом...
Java копирует ссылку по значению. Таким образом, если вы измените ее на что-то другое (например, используя new
), то ссылка не изменится вне метода. Для нативных типов она всегда передается по значению.
Взгляните на этот код. Этот код не будет генерировать NullPointerException
... Он напечатает «Vinay»
public class Main {
public static void main(String[] args) {
String temp = "Vinay";
print(temp);
System.err.println(temp);
}
private static void print(String temp) {
temp = null;
}
}
. Если Java передана по ссылке, тогда она должна была сгенерировать NullPointerException
, поскольку ссылка установлена на Null.
Сначала давайте поймем Выделение памяти в Java: Стек и "куча" являются частью Памяти, которую JVM выделяет в различных целях. Стековая память предварительно выделяется потоку, когда это создается, поэтому, поток не может получить доступ к Стопке другого потока. Но "куча" доступна всем потокам в программе.
Для потока, Стек хранит все локальные данные, метаданные программы, ссылки на данные типа примитива и ссылки на объект. И, "куча" ответственна за устройство хранения данных фактического объекта.
Book book = new Book("Effective Java");
В вышеупомянутом примере, ссылочная переменная является "книгой", которая хранится в стеке. Экземпляр, созданный новым оператором-> новая Книга ("Эффективный Java"), хранится в "куче". Касательно переменной "книги" имеет адрес объекта, выделенного в "куче". Скажем, адрес 1001.
Рассматривают передачу примитивного типа данных т.е. интервала, плавания, дважды и т.д.
public class PrimitiveTypeExample {
public static void main(string[] args) {
int num = 10;
System.out.println("Value before calling method: " + num);
printNum(num);
System.out.println("Value after calling method: " + num);
}
public static void printNum(int num){
num = num + 10;
System.out.println("Value inside printNum method: " + num);
}
}
, Вывод: Значение перед вызывающим методом: 10 Значений внутри printNum метод: 20 Значений после вызывающего метода: 10
международная цифра =10;-> это выделяет память для "интервала" в Стопке рабочего потока, потому что, это - тип примитива. Теперь, когда printNum (..) назван, частный стек создается в том же потоке. Когда "цифра" передается этому методу, копия "цифры" создается в стековом фрейме метода. цифра = num+10;-> это добавляет 10 и изменяет международную переменную в стековом фрейме метода. Поэтому исходная цифра вне стекового фрейма метода остается неизменной.
Рассматривают, пример передачи объекта пользовательского класса как аргумент.
В вышеупомянутом примере, касательно переменной "книги" находится в стопке потока, выполняющего программу, и объект класса Книга создается в Пространстве "кучи", когда программа выполняет новую Книгу (). Эта ячейка памяти в "куче" отнесена "книгой". Когда "книга" передается как аргумент метода, копия "книги" создается в частном стековом фрейме метода в той же стопке потока. Поэтому скопированная ссылочная переменная указывает на тот же объект класса "Книга" в "куче".
ссылочная переменная в стековом фрейме метода устанавливает новое значение к тому же объекту. Поэтому это отражается, когда исходный касательно переменной "книги", получает ее значение. Обратите внимание, что в случае передающей ссылочной переменной, если она инициализируется снова в вызываемом методе, она затем указывает на новую ячейку памяти, и любая операция не влияет на предыдущий объект в "куче".
Поэтому, когда что-либо передается как аргумент метода, это всегда - объект Стека - или примитивная или ссылочная переменная. Мы никогда не передаем что-то, что хранится в "куче". Следовательно, в Java, мы всегда передаем значение в стеке, и это - передача значением.
A: Java действительно управляет объектами ссылкой, и все переменные объекта являются ссылками. Однако Java не передает аргументы метода ссылкой; это передает их значением.
Берут badSwap () метод, например:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
, Когда badSwap () возвраты, переменные передали, поскольку аргументы будут все еще содержать свои исходные значения. Метод также перестанет работать, если мы изменим тип аргументов от интервала до Объекта, так как Java передает ссылки на объект значением также. Теперь, вот то, где это становится хитрым:
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
, Если мы выполняем это основное () метод, мы видим следующий вывод:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
метод успешно изменяет значение pnt1, даже при том, что это передается значением; однако, подкачка pnt1 и сбоев pnt2! Это - основной источник беспорядка. В основном () метод, pnt1 и pnt2 является не чем иным как ссылками на объект. При передаче pnt1 и pnt2 к хитрому () метод Java передает ссылки значением точно так же, как любой другой параметр. Это означает, что ссылки, переданные методу, являются на самом деле копиями исходных ссылок. Рисунок 1 ниже показывает две ссылки, указывающие на тот же объект после того, как Java передаст объект методу.
рисунок 1. Будучи переданным методу, объект будет иметь по крайней мере две ссылки
, Java копирует и передает ссылку значением, не объект. Таким образом управление методом изменит объекты, так как ссылки указывают на исходные объекты. Но так как ссылки являются копиями, подкачки перестанут работать. Ссылочная подкачка метода, но не исходные ссылки. К сожалению, после вызова метода, Вас оставляют только с неподкачанными исходными ссылками. Чтобы подкачка успешно выполнилась за пределами вызова метода, мы должны подкачать исходные ссылки, не копии.
Java передает параметры по значению. В Java нет возможности передать ссылку.
Но на уровне уровня привязки компилятора он использует ссылку, внутренне не предоставленную пользователю.
Это важно, так как экономит много памяти и улучшает скорость.
Открытый класс Test {
static class Dog {
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String nb) {
this.name = nb;
}
Dog(String sd) {
this.name = sd;
}
}
/**
*
* @param args
*/
public static void main(String[] args) {
Dog aDog = new Dog("Max");
// we pass the object to foo
foo(aDog);
Dog oldDog = aDog;
System.out.println(" 1: " + aDog.getName().equals("Max")); // false
System.out.println(" 2 " + aDog.getName().equals("huahua")); // false
System.out.println(" 3 " + aDog.getName().equals("moron")); // true
System.out.println(" 4 " + " " + (aDog == oldDog)); // true
// part2
Dog aDog1 = new Dog("Max");
foo(aDog1, 5);
Dog oldDog1 = aDog;
System.out.println(" 5 : " + aDog1.getName().equals("huahua")); // true
System.out.println(" part2 : " + (aDog1 == oldDog1)); // false
Dog oldDog2 = foo(aDog1, 5, 6);
System.out.println(" 6 " + (aDog1 == oldDog2)); // true
System.out.println(" 7 " + (aDog1 == oldDog)); // false
System.out.println(" 8 " + (aDog == oldDog2)); // false
}
/**
*
* @param d
*/
public static void foo(Dog d) {
System.out.println(d.getName().equals("Max")); // true
d.setName("moron");
d = new Dog("huahua");
System.out.println(" -:- " + d.getName().equals("huahua")); // true
}
/**
*
* @param d
* @param a
*/
public static void foo(Dog d, int a) {
d.getName().equals("Max"); // true
d.setName("huahua");
}
/**
*
* @param d
* @param a
* @param b
* @return
*/
public static Dog foo(Dog d, int a, int b) {
d.getName().equals("Max"); // true
d.setName("huahua");
return d;
}
}
пример кода, чтобы продемонстрировать влияние изменений объекта на различные функции.
Я думаю, что это простое объяснение могло бы помочь Вам понять, поскольку я хотел понять это то же самое, когда я боролся через это.
при передаче примитивных данных вызову функции, это довольно, копируется в аргумент функции и когда Вы передаете объект, это - ссылка, копируется в аргумент функции. Говоря об объекте, Вы не можете изменить скопированную ссылку - , переменная аргумента ссылается к в функции вызова.
Рассматривают этот простой пример, Строка является объектом в Java и когда Вы измените содержание строки, ссылочная переменная теперь укажет на некоторую новую ссылку, поскольку Строковые объекты неизменны в Java.
String name="Mehrose"; // name referencing to 100
ChangeContenet(String name){
name="Michael"; // refernce has changed to 1001
}
System.out.print(name); //displays Mehrose
Довольно простой, потому что, поскольку я упомянул, Нельзя изменить скопированную ссылку в функции вызова. Но проблема с массивом при передаче массива Строки/Объекта. Давайте посмотрим.
String names[]={"Mehrose","Michael"};
changeContent(String[] names){
names[0]="Rose";
names[1]="Janet"
}
System.out.println(Arrays.toString(names)); //displays [Rose,Janet]
, Поскольку мы сказали, что не можем изменить скопированную ссылку в вызове функции, и мы также видели в случае единственного Строкового объекта. Причина является именами [] ссылка переменной против скажем, 200 и называет [0] ссылка против 205 и так далее. Вы видите, что мы не изменили имена [], ссылаются на него неподвижные точки к старому та же ссылка все еще после вызова функции, но теперь называет [0] и называет [1], ссылка была изменена. Мы Все еще стоим на нашем определении, что мы не можем изменить ссылку ссылочной переменной, таким образом, мы не сделали.
то же самое происходит, когда Вы передаете Студенческий объект методу, и Вы все еще можете изменить Студенческое имя или другие атрибуты, точка, мы не изменяем фактический Студенческий объект скорее, мы изменяем содержание его
, Вы не можете сделать этого
Student student1= new Student("Mehrose");
changeContent(Student Obj){
obj= new Student("Michael") //invalid
obj.setName("Michael") //valid
}
Как выпускник информатики и как Разработчик программного обеспечения в общем... и изученный компиляторы и языки программирования... Java передает объекты ссылкой. Который передает значение ссылки, которая не отличается о том, как C++ или C делают.