Помогите, пожалуйста разобраться с ссылками в java.
Вот хороший пример:
public class TestClass {
public static void main(String[] args) {
int a = 7;
String s = "asd";
Person p = new Person("bb1", 6);
method1(a);
method2(s);
method3(p);
System.out.println(a); //7 - это потому что не было присваивания, верно?
System.out.println(s); //asd - тут тоже вроде бы понятно
System.out.println(p); //qwerty - а вот тут - почему только тут содержимое объекта меняется?
}
public static void method1(int a) {
++a;
a++;
}
public static void method2(String s) {
s = "bfr";
}
public static void method3(Person p) {
p.setName("qwerty");
}
}
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " " + age;
}
public void setName(String name) {
this.name = name;
}
}
Все параметры метода передаются в джаве по значению.
1) передавая примитив в метод, значение просто копируется
public static void method1(int a) {
++a;
a++;
}
т.е. внутри метода создается локальная переменная с именем а, и ее изменение никак не влияет на состояние переменой а в методе main
2) Передавая в метод параметр ссылочного типа, вы передаете копию указателя.
public static void method2(String s) {
s = "bfr";
}
т.е. s - это какое-то значение 0xA12s, оно указывает на обьект в памяти "asd", и когда вы передаете s в метода, копируется само значение указателя 0xA12s. Т.е. по факту тоже самое что с int. Т.е. от того, что вы измените ссылку s на 0x12abc ничего не изменится, потому что это внутри метода мейн ссылка останется прежней.
3) Когда вы передаете Person, опять же тупо копируются ссылка на этот обьект.
public static void method3(Person p) {
p.setName("qwerty");
}
Т.е. внутри main p=0x123 -> (какая-то область в памяти) и
внутри method3 p=0x123 -> (та же область в памяти)
когда вы вызываете сеттер идет разименование ссылки, вызывается метод на том обьекте, ссылку на который вы передали. И меняется его значение в пямяти, т.е.
до : p=0x123 -> ("bb1", 6)
после: p=0x123 -> ("qwerty", 6)
т.е. когда метод закончился указатель все еще смотрит на туже область в памяти только теперь, там в поле имя, вместо ссылки на бб1 ссылка на кверти.
Рекоммендую включить гугл транслейт и обратиться к похожим вопросам: http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
Если у вас имеется некоторый метод, как, например, этот
public static void method2(String parameter) {
parameter = "bfr";
}
И вы его вызываете как
String argument = "asd";
method2( argument);
то параметр метода инициализируется аргументом, указанным при вызове. То есть это можно представить себе следующим образом
public static void method2( /*String parameter*/) {
String parameter = argument;
parameter = "bfr";
}
Как видно, в методе меняется значение переменной parameter
. Сначала ей присваивается значение переменной argument
, а затем новое значение строкового литерала "bfr"
Сама исходная переменная argument
не изменилась. Ей ничего не было присвоено.
Что касается этого метода
public static void method3(Person p) {
p.setName("qwerty");
}
то здесь также параметр с именем p
получил копию значения своего аргумента. Сам аргумент в методе не меняется. Но так как после вызова функции параметр, получивший значение аргумента, указывает на тот же самый объект, что и аргумент, то с его помощью можно изменить адресуемый объект.
То есть в этом методе изменяется не аргумент, а объект, на который ссылается аргумент, так как параметр получает ту же самую ссылку на объект.
int
- примитивный тип, а вот s уже такой же экземпляр класса String
, как и p экземпляр класса Person
(именно поэтому String пишется с большой буквы) и в метод передается ссылка на ячейку памяти.
Класс String по сути массив символов.
Но у Stringa есть несколько ньюансов в инициализации. Так например:
s1='string';
s2='string';
s1==s2; // true
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Обращаюсь к VK API раз в секунду (Threadsleep(1000)), пишу несколько сообщений подряд боту (быстро), и получаю эксепшн: ApiTooManyException: Too many requests per second (6): Too many requests...
Получается, это дублирующие друг друга вещиМожет, есть какие-то реальные различия?
Проблема в следующем: Есть автотест который должен выполнять Drag&Drop элементов в определенном порядкеDrag&Drop реализован в тесте следующим...