Объекты управления памятью Java против примитивных типов - PullRequest
0 голосов
/ 04 декабря 2018

Я немного запутался из-за нескольких моментов, касающихся управления памятью Java.

Понял, в чем разница между стеками и кучей, и я посмотрел подходящий пример того, что это за память, когда мы выполняем некоторый код.

Я взял, например, несколько строк

public static void main(String[] args)
{
    int a = 5;
    calculate(a);
    System.out.println(a); //will print 5 not 50
}
private static void calculatee(int a)
{
    a = a * 10;
}

Я понял, что происходит в стеке и в куче.Переменная не возвращается, и в этом случае нет ссылки на кучу.

, в то время как в этом примере:

public static void maina(String[] args)
{
    Customer customer = new Customer("John");
    setAName(customer);
    System.out.println(customer.getName()); // this will return Philip
}

private static void setAName(Customer c)
{
    c.setName("Philip");
}

Я вижу, что состояние объекта изменилось на этот раз!

Стеки - это не общие мысли, но куча - общая!Что имеет смысл для меня, что клиент объекта изменил свою ценность с Джона на Филиппа, когда я его печатаю!Большой!все имеет смысл!

Однако я ожидал, что если я сделаю это

public static void main(String[] args)
{
    Integer i = new Integer(5);
    calculate(i);
    System.out.println(i); // printing 5 and not 50
}
private static void calculate(Integer i)
{
    i = i * 10;
}

, я получу 50, а не 5!

В этом случае Integer - это объект, а япри условии, что он создан в куче!

Забавно, что если я оберну Integer внутри Customer, я получу 50 вместо 5.

Почему это происходит?Разве целочисленный тип не создается в куче?

1 Ответ

0 голосов
/ 04 декабря 2018

Это проблема ссылок, а не куч и стеков.

При вызове метода calculate вы передаете ссылку (в вашем случае, i из main).

Хитрость в том, что Java создаст новую ссылку внутри calculate.Так что i внутри calculate и i внутри main могут изначально "указывать" на один и тот же объект, но они не являются "одинаковыми".

Итак, если вы измените i внутри calculate объекта, полученного в результате умножения, вы автоматически не изменяете ссылку i внутри main.

С Customer все по-другому.Вы никогда не измените, где c в setAName указывает на.Вы изменяете одну ссылку внутри объекта, но обе customer внутри main и c в setAName по-прежнему указывают на этот один объект!

Здесь два дерьмовых Paintчертежи, поясняющие, что я имею в виду (числа с префиксом 0x являются ссылками):

Для целочисленного примера:

Integer Graph

Для примера клиента:

Customer Graph

Не стесняйтесь возвращаться с любыми вопросами.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...