Объекты как параметры методов

Последнее обновление: 16.09.2025

В прошлой теме была рассмотрена передача параметров в метод. Объекты классов, как и данные примитивных типов, также могут передаваться в методы. Однако в данном случае есть одна особенность - при передаче объектов в качестве значения передается копия ссылки на область в памяти, где расположен этот объект.

Сначала рассмотрим более детально, что у нас происходит при передача параметров примитивных типов - числовых типов как int, double и т.д., типа char и boolean:

class Program{

    public static void main(String[] args) {  

        int num = 22;
        Calcualtor calc = new Calcualtor();
        calc.twice(num);
        System.out.printf("num in main (after twice): %d\n", num);
    }
}
class Calcualtor{

    void twice(int n){
		
        n = n + n;
        System.out.printf("n in twice: %d\n", n);
	}
}

Здесь в методе main значение переменной num передается в метод calc.twice() параметру n:

calc.twice(num);

В методе calc.twice() значение параметра n (которому передается значение переменной num) увеличивается в два раза:

void twice(int n){
		
    n = n + n;
    System.out.printf("n in twice: %d\n", n);
}

И тут возникает главный вопрос: увеличится ли значение переменной num или нет после выполнения метода calc.twice() и почему? Посмотрим на консольный вывод программы:

n in twice: 44
num in main (after twice): 22

По результату программы мы видим, что значение параметра n в методе twice увеличилось в два раза (как и ожидалось), а значение переменной num после выполнения метода twice не изменилось. При вызове метода calc.twice() параметр n в этом методе получает копию значения переменной num, то есть число 22:

Передача параметров по значению в Java

Когда вызывается метод calc.twice(), в область памяти, которая предназначена для параметра n, копируется значение переменной num - то есть число 22. После этого параметр n и переменная num никак не связаны - у них разные участки памяти, и изменение значениия одного из них никак не сказывается на другом. Поэтому изменение параметра n никак не влияет на переменную num.

Особенностью переменных других типов является то, что они хранят ссылку на область в памяти, где расположен объект. Рассмотрим небольшой пример:

class Program{

    public static void main(String[] args) {  

        Person bob = new Person();
        bob.age = 22;
        System.out.printf("bob.age in main (before twice): %d\n", bob.age);

        Calcualtor calc = new Calcualtor();
        calc.twice(bob);

        System.out.printf("bob.age in main (after twice): %d\n", bob.age);
    }
}
class Person{ 

    int age;
}

class Calcualtor{

    void twice(Person p){
		
        p.age = p.age + p.age;
        System.out.printf("p.age in twice: %d\n", p.age);
	}
}

Здесь метод twice класса Calculator теперь принимает объект типа Person, у которого есть целочисленное поле age. И в методе twice аналогичным образом это поле увеличивается в два раза.

 void twice(Person p){
		
    p.age = p.age + p.age;
    System.out.printf("p.age in twice: %d\n", p.age);
}

В методе main определяем переменную bob типа Person и передаем ее значение в метод twice:

Person bob = new Person();
.......................
calc.twice(bob);

Посмотрим на консольный вывод программы:

bob.age in main (before twice): 22
p.age in twice: 44
bob.age in main (after twice): 44

Здесь мы видим, что значение поля age у объекта, на который указывает переменная bob, изменилась. Почему? Так как в метод twice по сути передавается копия ссылки на область памяти, в которой находится объект Person, то переменная bob и параметр p метода twice будут указывать на один и тот же объект в памяти:

Передача объектов в метод в Java

Поэтому после выполнения метода у объекта, адрес которого хранит переменная bob и который передается в метод, будет изменено значение age c 22 на 44.

От этого случая следует отличать другой случай:

class Program{

    public static void main(String[] args) {  

        Person bob = new Person();
        bob.age = 22;
        System.out.printf("bob.age in main (before twice): %d\n", bob.age);

        Calcualtor calc = new Calcualtor();
        calc.twice(bob);

        System.out.printf("bob.age in main (after twice): %d\n", bob.age);
    }
}
class Person{ 

    int age;
}

class Calcualtor{

    void twice(Person p){
		
        p = new Person();      // создаем новый объект
        p.age = 44;
        System.out.printf("p.age in twice: %d\n", p.age);
	}
}

В метод twice также передается копия ссылки на объект Person. Однако в самом методе мы изменяем не отдельные значения объекта, а пересоздаем объект с помощью конструктора и оператора new. В результате в памяти будет выделено новое место для нового объекта Person, и ссылка на этот объект будет привоена параметру p:

void twice(Person p){
		
    p = new Person();      // создаем новый объект
    p.age = 44;
    System.out.printf("p.age in twice: %d\n", p.age);
}

То есть после создания нового объекта Person параметр p и переменная bob в методе main будут хранить ссылки на разные объекты. Переменная bob, которая передавалась в метод, продолжит хранить ссылку на старый объект в памяти. Поэтому ее значение не меняется, что мы и увидим по консольному выводу:

bob.age in main (before twice): 22
p.age in twice: 44
bob.age in main (after twice): 22
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850
Morty Proxy This is a proxified and sanitized view of the page, visit original site.