#java
Здравствуйте! Пересев с С# узнал, что в Java все параметры передаются по значению.
1) Ссылка ссылается на имеющийся объект, и если до передачи на него ссылалась одна
ссылка, то теперь их две?
2) Создаётся новый объект в куче, и в пределах блока кода метода работаешь с новосозданным
объектом. При этом после завершения работы метода, изначальный объект остаётся не изменённым?
Созданный объект в методе уже стал на учёте у сборщика мусора?
Прочитав пару статей про передачу параметров в Java, решил поэкспериментировать.
Есть свой класс со строковым полем и двумя методами. Первый метод меняет поле объекта,
а второй меняет значение скопированной ссылки.
Вот класс:
class MyClass {
String s;
public MyClass(String s) {
this.s = s;
}
public static void changeField(MyClass other) {
other.s = "**********";
}
public static void changeRef(MyClass other) {
other = new MyClass("----------");
}
Однако почему-то, метод changeField изменяет объект, в то время как changeRef - нет.
MyClass obj1 = new MyClass("1");
MyClass obj2 = new MyClass("2");
MyClass.changeField(obj1);
MyClass.changeRef(obj2);
System.out.println(obj1.s);
System.out.println(obj2.s);
Вывод исполнения программы:
**************
2
Ответы
Ответ 1
Как вы сказали, в Java передаётся ссылка на объект(за исключением примитивных классов типа int, long and etc.) при этом, под эту ссылку выдается своя память. В методе changeField происходит изменение самого объекта. И вы видите эти изменения за пределами функции. В методе changeRef происходит создание нового экземпляра класса и ссылку на него записываете в ту область памяти которая была выделена для копии ссылки передаваемого объекта. Таким образом вы не меняете исходную ссылку и исходный объект. И да, при передаче объекта в метод, создаётся дополнительная ссылка, т.е. их становится две, как вы написали в вашем вопросе.Ответ 2
В java нет передачи по ссылке в том смысле, что члены ссылочных типов вы менять можете, а вот сами ссылки, указывающие на экземпляры этих типов - нет. В C# по сути все точно так же: тот же самый код, что вы написали, будет точно так же работать и там. При вызове changeField вы меняете поле экземпляра, но не сам экземпляр. А при вызове changeRef вы пытаетесь изменить саму ссылку, но ссылки остаются неизменными, так как в метод вы передаете только их копии. Отличие между Java и C# будет в том, что C# с помощью ключевых слов ref и out позволяет менять и сами ссылки на объекты. В java этого нетОтвет 3
Всетаки букварь по Java прочитать стоит. Все передается по значению. В java нет передачи по ссылке. Вот только MyClass obj1 = new MaClass("1") означает что в obj1 лежит не объект а ссылка на него. В тоже время long val = 1l означает что в val храниться 1, но Long val = new Long(1) - уже будет означать что val храниться ссылка на объект типа Long ( не путать с примитивным типом long) Вот тут подробнее https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html Т.е. разница между Reference types и Primitive Types
Комментариев нет:
Отправить комментарий