Сохраните файл с расширением «.html». Например, «index.html». И тогда вы можете прямо на файл и выберите «открыть с» и выберите нужный браузер. Или же вы можете сначала открыть свой браузер. Затем перейдите в меню Файл -> Открыть -> Выбрать index.html
.Есть две проблемы:
Integer#set(i)
. В противном случае вы можете просто использовать его. Чтобы заставить его работать, нужно переназначить возвращаемое значение метода inc()
.
integer = inc(integer);
Чтобы узнать больше о передаче по значению, вот еще один пример:
public static void main(String... args) {
String[] strings = new String[] { "foo", "bar" };
changeReference(strings);
System.out.println(Arrays.toString(strings)); // still [foo, bar]
changeValue(strings);
System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
strings[1] = "foo";
}
1) Только копия ссылки отправляется как значение в формальный параметр. Когда переменной формального параметра присваивают другое значение, ссылочные изменения формального параметра, но ссылка фактического параметра остается тем же, упаковывают этого целочисленного объекта.
общедоступный класс UnderstandingObjects {
public static void main(String[] args) {
Integer actualParam = new Integer(10);
changeValue(actualParam);
System.out.println("Output " + actualParam); // o/p =10
IntObj obj = new IntObj();
obj.setVal(20);
changeValue(obj);
System.out.println(obj.a); // o/p =200
}
private static void changeValue(Integer formalParam) {
formalParam = 100;
// Only the copy of reference is set to the formal parameter
// this is something like => Integer formalParam =new Integer(100);
// Here we are changing the reference of formalParam itself not just the
// reference value
}
private static void changeValue(IntObj obj) {
obj.setVal(200);
/*
* obj = new IntObj(); obj.setVal(200);
*/
// Here we are not changing the reference of obj. we are just changing the
// reference obj's value
// we are not doing obj = new IntObj() ; obj.setValue(200); which has happend
// with the Integer
}
}
класс IntObj {Целое число a;
public void setVal(int a) {
this.a = a;
}
}
Целое число неизменяемо. Вы можете обернуть int в свой собственный класс-оболочку.
class WrapInt{
int value;
}
WrapInt theInt = new WrapInt();
inc(theInt);
System.out.println("main: "+theInt.value);
Здесь вы видите не перегруженный +
опаратор, а поведение автобокса. Класс Integer
является неизменным, и ваш код:
Integer i = 0;
i = i + 1;
рассматривается компилятором (после автобокса) как:
Integer i = Integer.valueOf(0);
i = Integer.valueOf(i.intValue() + 1);
, поэтому вы правы в своем заключении, что экземпляр Integer
изменяется, но не скрытно - это согласуется с определением языка Java: -)
Я думаю, что именно автобоксинг сбивает вас с толку.
Эта часть вашего кода:
public static Integer inc(Integer i) {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println("Inc: "+i);
return i;
}
На самом деле сводится к коду, который выглядит так:
public static Integer inc(Integer i) {
i = new Integer(i) + new Integer(1);
System.out.println("Inc: "+i);
return i;
}
Что, конечно же... не изменит переданную ссылку.
Вы можете исправить это с помощью чего-то вроде этого
public static void main(String[] args) {
Integer integer = new Integer(0);
for (int i =0; i<10; i++){
integer = inc(integer);
System.out.println("main: "+integer);
}
}
Если вы измените свою функцию inc () на это
public static Integer inc(Integer i) {
Integer iParam = i;
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println(i == iParam);
return i;
}
, то вы увидите, что она всегда выводит «false». Это означает, что добавление создает новый экземпляр Integer и сохраняет его в локальной переменной i («local», потому что i на самом деле является копией переданной ссылки), оставляя переменную вызывающей нетронутый метод.
Integer - это неизменяемый класс, что означает, что вы не можете изменить его значение, но должны получить новый экземпляр. В этом случае вам не нужно делать это вручную следующим образом:
i = new Integer(i+1); //actually, you would use Integer.valueOf(i.intValue()+1);
вместо этого это делается автобоксингом.
Здесь вы правы:
Integer i = 0;
i = i + 1; // <- I think that this is somehow creating a new object!
Первое: Integer является неизменяемым.
Второе: класс Integer не переопределяет оператор +
, в этой строке задействован автобоксинг и автобоксинг (В старых версиях Java вы бы получили ошибку на вышеуказанной строке).
Когда вы пишете i + 1
, компилятор сначала преобразует Integer в (примитив) int
для выполнения сложения: автоунбоксинг. Далее, выполняя i =
, компилятор преобразует int
в (новый) Integer: автобоксинг.
Таким образом, +
фактически применяется к примитивным int
ам.