Когда я передаю объект методу через параметр, передается ли объект по значению или по ссылке? Вопрос исходит из этого кода:
int a = 2;
cambiar(a);
System.out.println(a);
public static void cambiar(int c) {
c = 10;
}
В приведенном выше коде я уже знал, что не собираюсь a
каким-либо образом изменять a, пока метод не вернет int и не сохранит его. Но что происходит в следующем коде?
class otraCualquiera {
Partidas partidas = new Partidas();
Ventana ventana = new Ventana();
Gestor gestor = new Gestor(ventana,partidas);
}
class culquiera {
private Ventana view;
private Partidas play;
public Gestor(Ventana v, Partidas p) {
view = v;
play = p;
}
}
Главный вопрос, почему я могу напрямую модифицировать другие классы из класса any? ( view.setTitle("View sería un jframe")
) и из первого кода, который я показал, я не могу изменить int
?
Прежде всего...
В Java нет такой вещи, как передача по ссылке. Передача по значению (или по копии, как это называют некоторые) обязательна.
Вы скажете но когда я передаю массив по параметрам и я его модифицирую из метода в который я его передаю он меняется, я не передаю копию массива
Кажется, мой аргумент не работает, но я объясню:
То, что вы сохраняете в непримитивной переменной , — это не сам объект, а адрес или идентификатор объекта в динамическом пространстве памяти. Когда вы передаете переменную в качестве параметров, вы передаете копию этого адреса.
Предложенный вами случай
Вы создали три объекта типа
Partidas
,Ventana
иGestor
.Объект
Gestor
хранит в своих атрибутах адрес объектовPartidas
иVentana
то, что вы передали им в качестве параметров. Копия переданных объектов не создана.У вас есть копия адреса объекта. Если вы добавите следующую строку в конструктор менеджера сразу после уже имеющихся:
Вы просто сделаете так, чтобы параметр
v
больше не хранил адрес объекта типаVentana
. В классеotraCualquiera
переменная по-ventana
прежнему будет иметь правильный адрес.Таким образом, передача ВСЕГДА по копии значения, в отличие, скажем, от C или C++, где разрешена передача по ссылке. Что вы должны понимать, так это то, что в случае объектов значение, которое хранит переменная, является адресом или идентификатором объекта, а не самим объектом.
Если вы хотите найти способ изменить переменную примитивного типа (например, int) из другого метода, которому вы ее передаете (что-то не очень распространенное, но полезное в некоторых рекурсивных алгоритмах), метод может быть чтобы иметь целое число в виде одноэлементного массива, тогда оно будет рассматриваться как объект, и вы будете передавать только копию его адреса (полноценная ссылка).
Обычно принято хранить его как объект
Integer
, но этот класс неизменяем.Краткие моменты, которые следует помнить, заключаются в том, что в Java:
Второй момент вызывает много путаницы. В Java, когда у нас есть следующая ситуация:
... мы обычно говорим, что значение переменной является «объектом», но такой способ выражения является повседневным упрощением — удобной неточностью. Если мы хотим разобраться в этом вопросе, мы должны понять, что в том, как работает Java, значением
saludos
является не объект, а ссылка на объект. Переменная, ссылка и объект — это три взаимосвязанные, но отдельные вещи, и вы должны внимательно следить за тем, какие операции на что влияют и каким образом. Например:saludos = "¡Saludos de nuevo!";
) изменяет значение переменной. Но значение переменной в данном случае является ссылкой, а не объектом. Присваивание не обращается к объектам — оно работает строго с переменными и их значениями.a == b
илиa != b
, смотрят на текущие значения переменных. Когда эти значения являются ссылками, то они смотрят на эти ссылки, но не обращаются к своим объектам.null
это ссылка, а не объект. Это ссылка без объекта по определению.saludo.length()
) или ссылка на член (objeto.variable
) отслеживает текущее значение переменной и обращается к объекту, соответствующему этой ссылке.На все приведенные вами примеры можно ответить, строго применяя эти правила. Например:
В этом примере вы даете, вопреки тому, что вы говорите, нет прямой модификации другого класса. То, что вы на самом деле делаете, это:
view
;setTitle
этого объекта, передав ему ссылку на объект"View sería un jframe"
.Само по себе это ничего не меняет; если и есть модификация, то косвенная, потому что метод что-
setTitle
то модифицирует прямо или косвенно вызывает такую модификацию через вызовы других методов.Если вы еще раз посмотрите на мой список, пункт № 1 — это единственный механизм, который фактически изменяет значение переменной. Ни одна из других точек не имеет «власти» изменять что-либо напрямую. Хотя сказать, как вы говорите
view.setTitle("View sería un jframe")
«модифицируетview
», — это популярный и упрощенный способ описания того, что происходит, на самом деле это не то, что происходит, когда мы строго смотрим на то, как все работает.В Java нет ссылок. Параметры передаются копированием (переменные базового типа языка или копированием адреса где они хранятся) ЭТО НЕ ПЕРЕХОД ПО ССЫЛКЕ!!!!!!!!. Передача по ссылке — это создание псевдонима переменной или объекта с другим именем, но ССЫЛАЕТСЯ на то же пространство памяти. Например:
ПРОСТРАНСТВО ПАМЯТИ 10 -> У нас есть объект person1, хранящийся в этом пространстве.Ссылка будет -> создать объект personReference, который является псевдонимом person1.
В заключение, ссылка подобна вызову области памяти различными способами без использования дополнительных ресурсов памяти.
В Java используется копия. содержимого переменной или, в случае объекта, адреса памяти, в котором он расположен. В обоих случаях содержимое переменной копируется в другую переменную ИЛИ адрес памяти объекта в другой объект (это то, что в C называется указателем). Разница в том, что Java обрабатывает его специальным образом, а не в C. непосредственно программист.