undefined

Переменные-ссылки

Java Syntax
2 уровень , 6 лекция
Открыта

— Привет, Амиго, это снова я – Элли. Прости, что постоянно так говорю, так просто принято на Земле в 31 веке. Я хочу рассказать тебе об особенностях переменных-ссылок и передаче в функции(методы) аргументов-ссылок.

— Я готов.

— Отлично, тогда слушай. Переменные-ссылки – это переменные всех типов, кроме примитивных. Такие переменные содержат в себе только адрес объекта (ссылку на объект).

— Переменные примитивных типов хранят в себе значения, а переменные типов-классов хранят ссылку на объекты этого же класса, ну или хранят null. Я все правильно говорю?

— Абсолютно верно.

— Так что же это такое — эта ссылка?

— Объект и ссылка на него связаны, примерно, как человек и его телефонный номер. Телефонный номер не является человеком, но номер можно использовать, чтобы звонить человеку, спрашивать у него какую-то информацию, руководить им или давать команды. Ссылка тоже используется для взаимодействия с объектом. Все объекты взаимодействуют друг с другом при помощи ссылок.

— Это как если бы люди общались друг с другом по телефону?

— Именно. При присваивании примитивного объекта, его значение копируется (дублируется). При присваивании же ссылочной переменной, копируется только адрес объекта (телефонный номер), сам же объект при этом не копируется.

— Ок, понял.

— Ссылка даёт ещё одно преимущество: можно передать ссылку на объект в какой-нибудь метод, и этот метод будет в состоянии модифицировать (изменять) наш объект используя ссылку на него, вызывая его методы и обращаясь к данным внутри объекта.

Пример 1
Тут значение m и n не меняется.
public class References
{
  public static void main (String[] args)
  {
    int m = 5;
    int n = 6;

    System.out.println("M=" +m+ " N=" + n);
    swap(m, n);
    System.out.println("M=" +m+ " N=" + n);
  }

  private static void swap(int a, int b)
  {
    int c = a;
    a = b;
    b = c;
  }
}
И вот почему.
Данный код аналогичен коду слева
public class References
{
  public static void main (String[] args)
  {
    int m = 5;
    int n = 6;

    System.out.println("M=" +m+ " N=" + n);
    int a = m, b = n;

    int c = a;
    a = b;
    b = c;

    System.out.println("M=" +m+ " N=" + n);
  }
}

— Переменным a и b присваиваются только значения 5(m) и 6(n) соответственно, a и b ничего не знают про (никак не влияют на) m и n.

— Честно говоря, я понял, что я ничего не понял. Можно еще пару примеров?

— В случае со ссылочным типом, можно было сделать так:

Пример 2
Тут данные объектов меняются
public class Primitives
{
  public static void main(String[] args)
  {
    Student olga = new Student();
    olga.name = "Olga";
    olga.age = 21;

    Student vera = new Student();
    vera.name = "Veronika";
    vera.age = 15;

    System.out.println("Olga is " + olga.age);
    System.out.println("Vera is " + vera.age);

    ageSwap(olga, vera);

    System.out.println("Olga is " + olga.age);
    System.out.println("Vera is " + vera.age);
  }

  private static void ageSwap(Student a,
                                    Student b)
  {
    int c = a.age;
    a.age = b.age;
    b.age = c;
  }

  static class Student
  {
    String name;
    int age;
  }
}
И вот почему.
Данный код аналогичен коду слева
public class Primitives
{
  public static void main(String[] args)
  {
    Student olga = new Student();
    olga.name = "Olga";
    olga.age = 21;

    Student vera = new Student();
    vera.name = "Veronika";
    vera.age = 15;

    System.out.println("Olga is " + olga.age);
    System.out.println("Vera is " + vera.age);

    Student a = olga, b = vera;

    int c = a.age;
    a.age = b.age;
    b.age = c;

    System.out.println("Olga is " + olga.age);
    System.out.println("Vera is " + vera.age);
  }

    



  static class Student
  {
    String name;
    int age;
  }
}

— Переменным a и b присваиваются ссылки на olga и vera соответственно, a и b меняют значения внутри объектов olga и vera.

— Так классы внутри других классов ещё можно объявлять? Круто!

— Но в остальном не очень-то и понятно.

— Не все сразу.

Комментарии (458)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Алексей 8 уровень, Ставрополь
12 марта 2021
Ура! Наконец таки понял! Все элементарно на самом деле. Cоздаем переменные а и b , которые ссылаются также как и переменные vera и olga на одни и те же объекты - соответственно Vera() и Olga(). И, изменив значение свойства age этих объектов через a.age и b.age, мы, если выведем на экран свойства vera.age и olga.age, увидим, что они тоже поменяли свое значение. Ведь, объекты одни. На мой взгляд, для начала было бы лучше сделать пример с одним объектом, а не с двумя, например: public class lesson5 { public static void main(String[] args) { Student Vera = new Student(); System.out.println(Vera.age); Student a = Vera; a.age = 18; System.out.print(Vera.age); } public static class Student{ int age = 25; } } В итоге программа сначала выведет, что Вере 25, а потом выведет, что Вере 18.
DeeperKyo 3 уровень, Уфа
25 февраля 2021
Далее по лекции порешал 3 epic задачки и все сразу стало понятно, кто тут не понял не зацикливайтесь. идите дальше пару лекций до задачек и после их решения придёт понимание! JR Super!!!
Дима 8 уровень, Комсомольск-на-Амуре
3 февраля 2021
И объясните пожалуйста в последнем коде, который начинается со слов-* И вот почему...*- что это за переменные такие объявляются- Student a = olga, b = vera; и далее уже идет танец с бубнами по замене переменных ссылок, как я понял. Ведь не показано нигде, какого типа эти переменные a и b, какие они String или int нигде ведь не указано? Разве не должно быть указано сначала в полях или где еще что это за переменные, в смысле какого типа они объявляются? Что здесь до меня не доходит, разжуйте пожалуйста?
Дима 8 уровень, Комсомольск-на-Амуре
3 февраля 2021
все равно мозг не может въехать в эти примеры, может он уже настолько стар и бесполезен?))(43 года(и это не аргументы функции). Почему всё таки в примере с цифрами функция не меняет значения, вот всё равно не могу понять? Может если в конце нее добавить return, то значения все таки поменяются, или ретурн не спасет?)) Разве при вызове функции swap на место a и b не должны подставиться автоматически значения m и n? И дальше идет обыгрывание чисел так, чтобы они поменялись потом на выводе. Тогда для чего эта функция создаётся, если она ничего не меняет? Тогда как правильно создать такую функцию, чтобы можно было сравнить ? Добавить в нее return в конце или что? Надо как то было рядом хотя бы написать такую функцию для сравнения и понимания, а не сразу переходить к ссылочным переменным и говорить - смотрите дети, а тут то девки меняются годами, вот бы в жизни так- написал функцию и сменил себе возраст, чтобы мозги помоложе были и понимали сразу что к чему)) Вот обязательно нужно понять в этом месте почему swap с числами ничего не меняет и как сделать этот swap , чтобы он менял всё таки числа? Разжуйте пожалуйста старику этот момент специалисты простым доступным языком, чтобы со спокойной душой уже идти дальше
BEAR 15 уровень, Минск
21 января 2021
Подскажите, плиз. Разобрал каждую строку в примере 2. В принципе, последовательность и необходимость всех действий понятна. Кроме вот этого блока в самом конце: static class Student { String name; int age; } Зачем он нужен, что он здесь? Или этот пример просто отрывок - часть большей программы (вырван из нее) ?
Andrew 22 уровень, Санкт-Петербург
12 января 2021
Я может и не Америку открою, но все же!!! Дамы и Господа! Надо знать английский язык!!! Это 40 % успеха!!! Вот пример "swap" - и сразу думаешь!!!! Что же это за чертовщина новая такая! Банальный перевод! swap - меняй! Ну и понятно! Меняем местами! Может и не прав я тут, но мысль то тут одна! Подтягивайте Юнглиш!!!
toxigent 7 уровень, Default-city
2 января 2021
Для понимания конструкции решил заморочиться в IDE

static class Student
    {
        String name;
        int age;
        int height;

        public Student(String name,int age)
        { this.name = name;
            this.age = age; }
    }
    public static void main(String[] args)
    {

        Student olga = new Student("Ольга ", 21);
        Student vera = new Student("Вера ",15);

        ageSwap(olga, vera);

        System.out.println(olga.name + olga.age);
        System.out.println(vera.name + vera.age);
    }

    private static void ageSwap(Student a,
                                Student b)
    {
        int c = a.age;
       a.age = b.age;
        b.age = c;
    }
Суть была в том, что переменная типа Student c именем olga хранит целый ряд параметров и именно они входя в метод копируются в новые переменные.
Alex Volk 3 уровень, Кишинев
16 ноября 2020
Статья поможет чуть лучше понять чего от Вас хотят ... мне помогло https://ru.hexlet.io/courses/java_101/lessons/java_instance_usage/theory_unit вернулся к понятиям )) понял что не стоит идти дальше пока хотя бы общее картину не до конца понял
Toxa 10 уровень, Санкт-Петербург
13 октября 2020
Сбивает с толку написание метода после тела main. Как и описание классов после main, неужели в Java так принято? Я понимаю зачем это в огромных программах,но в таких маленьких зачем классы описывать в конце?
Алексей Мирный 41 уровень, Москва
7 октября 2020
Честно говоря, я понял, что я ничего не понял.