#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
Комментариев нет:
Отправить комментарий