Подтвердить что ты не робот

Изменяется ли массив в методе?

Когда я пишу вот так:

public class test {

    void mainx()
    {
        int fyeah[] = {2, 3, 4};
        smth(fyeah);
        System.out.println("x"+fyeah[0]);
    }

    void smth(int[] fyeah)
    {
        fyeah[0] = 22;
    }
}

Он печатает x22;

Когда я пишу вот так:

public class test {

    void mainx()
    {
        int fyeah = 5;
        smth(fyeah);
        System.out.println("x"+fyeah);
    }

    void smth(int fyeah)
    {
        fyeah = 22;
    }
}

Он не печатает x22, а печатает x5.

Почему во второй версии функция не меняет значение? Изменяет ли значения только элементы массива?

4b9b3361

Ответ 1

Переменная fyeah в первом примере содержит ссылку на массив (а не массив), а целое число fyeah во втором примере содержит целое число.

Так как Java передает все по значению, произойдет следующее:

В случае с массивом: Будет отправлена ​​копия ссылки на массив, и исходный массив будет изменен.

В случае int: Копия целого будет изменена, а исходное целое не будет изменено.

Ответ 2

Это потому, что ваш int является примитивным, а метод smth создает локальную копию, поэтому он не печатает так, как вы хотите. Объекты также передаются по значению, но значение указателя в памяти. Поэтому, когда он изменяется, указатель остается в обоих методах, и вы видите изменение. Подробнее здесь

Ответ 3

Ok. Int в java (и на самом деле все языки с строгим набором данных) - это примитивный тип данных. Это всего лишь одна переменная этого типа данных. В java это означает, что он передан по значению методу. Поэтому, когда вы передаете аргумент, создается копия переданной переменной. Любые операции, выполняемые в методе, действуют на эту копию, а не на переданную переменную.

Фактически в java ВСЕ передается по значению, но вхождение в детали того, как это на самом деле истинно, с тем, что я собираюсь сказать, кажется неприемлемым.

С массивом... его набор переменных типа примитивных данных int. Таким образом, целая копия массива фактически не делается просто копией ссылки на память, в которой хранится массив. поэтому да значение int IN массива изменяется от операций в методе.

В коротких методах не изменяются внешние значения примитивов (int, float, double, long, char) с операциями в методе, вы должны вернуть полученное значение этих операций вызывающему, если вы хочу его получить. Операции изменяют значение для большинства объектов, а также массивов примитивов. Надеюсь, это поможет. Действительно не уверены в том, как низкий уровень. Может быть, кто-то еще может четко объяснить, почему его по стоимости. Я "получаю" это, но мне трудно помочь другим людям понять.

Ответ 4

int - это тип значения, поэтому 5 передается непосредственно в smth, который может изменять только локальную копию. Массив, с другой стороны, является ссылочным типом, поэтому элементы этого массива могут быть изменены.

Ответ 5

Увидев это немного менее технически, я бы сказал, что

    fyeah[0] = 22;

изменяет содержимое (объект, на который указывает) fyeah, а

    fyeah = 22;

изменяется (переменная) сама fyeah.
Другой пример:

void smth(Person person) {
    person.setAge(22);
}

меняет (содержимое) человека, пока

void smth(Person person) {
    person = otherPerson;
}

меняет переменную person - исходный экземпляр Person по-прежнему остается неизменным (и, поскольку Java имеет значение pass-by-value, переменная в вызывающем коде не изменяется этим методом)

Ответ 6

Подумайте об этом с точки зрения памяти: проанализируем вашу первую программу -

В mainx, fyeah - это массив int, поэтому его ссылка (или указатель, если я могу). Эта ссылка указывает на местоположение в памяти кучи, где хранится фактический массив int. Скажем, по адресу 100. Находится смежно отсюда три ints (скажем, начиная с адреса 100, 104 и 108 соответственно являются 2, 3 и 4).

Теперь вы вызываете свой метод smth и передаете ссылку. Внутри метода есть другая ссылка (типа массива int) с именем fyeah. Этот fyeah отлично отличается от справочника fyeah в методе mainx. Теперь, когда вы вызываете smth и передаете fyeah из mainx, fyeah внутри метода smth инициализируется, чтобы указывать на то же местоположение (то есть адрес памяти 100) Когда вы получаете доступ к элементу 0 из fyeah и присваиваете ему значение 22, он достигает области памяти 100 и записывает это значение 22. Когда вы вернетесь в свой метод mainx, ссылка fyeah по-прежнему относится к адресу памяти 100. Но значение, присутствующее в этом месте, теперь равно 22. Таким образом, вы получаете это значение при доступе к первому элементу из fyeah в mainx.

Теперь, ваша вторая программа. Ваш метод mainx объявляет int (а не массив, но простой int) и устанавливает его в 5. Эта переменная fyeah создается в стеке, а не в куче. Значение 5 сохраняется в стеке. Теперь вы вызываете smth и передаете эту переменную. В рамках метода smth вы снова объявляете переменную int, fyeah по имени (в качестве аргумента формального метода). Опять же, это отличается от fyeah метода mainx, и этот fyeah также создается в стеке. Эта переменная будет инициализирована значением 5, скопировано из fyeah, которое вы передали в smth как аргумент. Обратите внимание, что на fyeah есть две разные копии, как на стек, так и на значение 5. Теперь вы назначаете fyeah в smth значение 22. Это не повлияет на fyeah mainx, поэтому, когда вы вернетесь к mainx и получите доступ к fyeah, вы увидите 5.