2015-05-12 3 views
4

Я узнал о ссылках и типах данных в Java, и этот код по-прежнему меня озадачивает. Я понимаю, что все примитивные типы в Java - это типы значений (байты, короткие, int, long, float, double, boolean, char), а когда вы используете строку или объект, это ссылочный тип. Когда меня научили объявлять и инициализировать переменную, мне сказали подумать, как создать коробку. Поэтому, если я создаю переменную «y» и даю ей значение «5», это похоже на то, что я создал поле с именем «y», содержащее значение 5. Мой учитель сказал, что если я затем попытаюсь вызвать y в метод (ознакомьтесь с приведенным ниже кодом для более подробной информации) значение останется нетронутым, потому что это примитивный тип данных, поэтому я передаю только 5, а не переменную CONTAINS 5. Ну, я смущен, потому что, если я прохожу в значение 5, почему бы следующий метод не добавить на него.Все еще не уверены, почему это целое число остается неизменным

public class ReferenceAndValueTypes { 
    public static void main(String[] args) { 

     int y = 5; 
     addOneTo(y); 

     System.out.println(y); 

    } 


    static void addOneTo(int number){ 
     number = number + 1; 
    } 
} 

Выход 5, и это меня смущает. Учитель говорит, что это потому, что int - это тип значения, поэтому мы не передаем переменную y, и мы не работаем над этой переменной, а скорее значение этой переменной. Однако значение этой переменной равно 5, и поскольку метод добавляет один, не должно быть 6? Или, потому что y является типом значения, метод не может работать с ним, поэтому ему просто нужно распечатать начальное значение y, которое равно 5?

+2

Вы работаете на ** копии ** из эта переменная. –

+1

значение равно 6, но только в методе addOneTo. (попробуйте распечатать числовую переменную в методе addOneTo) ... вы передаете значение «5» вашему методу добавления. вы добавляете 1 к нему -> дает «6». НО от того, где вы его назвали .. значение не изменилось (как это должно быть ... вы просто передали значение VALUE вашему методу) – griFlo

+3

@Seelenvirtuose Я не уверен, что здесь разумный обман, поскольку OP не " t понимать разницу между передачей по значению и передачей по ссылке. –

ответ

3

Java-примитивы (int, long, boolean и т. Д.) Не являются ссылками, они являются фактическими значениями. Когда у вас есть addOneTo(y);, addOneTo получает копию значения. Это скопированное значение увеличивается на единицу, а затем теряется при выходе метода.

Как аналог, когда вы видите параметр примитивного метода, вы можете думать о нем как к копировальной машине. Напротив, ссылка на объект такая же, как передача блокнота с чем-то написанным на нем. Метод увидит тот же объект, а не его копию, и поэтому внесенные в него изменения будут присутствовать после выхода метода.

Изменение имени параметра может сделать это немного понятнее

static void addOneTo(int numberA) { // numberA is not the same as the int in the calling method, it's just an exact copy of it 
    numberA = numberA + 1; // numberA is now incremented by one 
    // method exits, numberA is lost 
} 

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

public static void main(String[] args) { 
    int x = 3; 
    addOneTo(x); // x is still 3 
    x = addOneTo(x); x is now 4 
} 

static int addOneTo(int number) { 
    return number + 1; 
} 
+1

Большое спасибо за эту аналогию –

+0

, если вы хотите, чтобы переменная изменения вернулась, вы можете изменить этот метод, чтобы иметь тип int в качестве возвращаемого значения и вернуть его. может быть, пример для этого? – Dude

+0

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

0

Поскольку примитивные типы в Java передаются по значению, а не по ссылке. Внутри addOne()i рассматривается как локальная переменная, которая копируется из переданного аргумента, поэтому любые изменения в ней не изменяют переменную, которая передается вызывающим.


P.S. Это также действительно работает для объектов. Например, этот фрагмент кода:

void changeString(String s) { 
    s = new String("new"); 
} 

String s = "old"; 
changeString(s); 
System.out.println(s); 

печатает "old", потому что в changeString(), s ссылка копируется, тем самым изменяя его внутри метода (назначение новой ссылки) не оказывает никакого влияния на s переменной вызывающего абонента.

-1

Насколько это просто, java написана как pass-by-value. Если вы увеличиваете число в вашем методе addOneTo, вы меняете значение ссылки вашего номера параметра. по этому номер больше не ссылается на вашу оригинальную переменную y и, следовательно, увеличивает ее. Это не работает ни на одном примитивном типе.

+0

«значение ссылки вашего параметра» - что это значит? –

+0

Это должно означать значение, переданное 'addOneTo', представляющее параметр числа в памяти. – SomeJavaGuy

+0

«* номер больше не ссылается на ваш исходный y-переменный и, следовательно, увеличивает его *« Что означает это * это *? –

-1

Если переменная x имеет ссылочный тип, то это указывает на объект. Если он содержит тип значения, он указывает на значение. Когда вы вызываете какую-то функцию f(x), вещь, которая передается f, является тем, что xуказывает на, а не x.

Так вот, если бы вы сказали что-то вроде

int y[] = new int[1]{5} 

, а затем сказал

number[0] = number[0] + 1; 

внутри addOneTo, то значение y будет изменен вне --- вещь, что addOneTo является действующий на массив, содержащий это число.

С другой стороны, когда int y = 5, тогда вы действуете, это номер. Вы делаете новое имя, которое указывает на то же значение (5), и когда вы говорите

number = number + 1; 

, что вы на самом деле имею в виду:

number2 = number + 1; 
number = number2; 

а затем выбросить результат.

+1

Он не указывает на значение, оно * является * значением (или, может быть, * имеет * значение). –

+0

@OliverCharlesworth Я думаю, что говорить «переменная точка» в общем случае является справедливым утверждением --- они относятся к адресам памяти, которые содержат значения. 'y = 5' означает, что« адрес памяти, на который ссылается 5, содержит значение 5 », где в качестве« y = new int [1] {5} «означает» адрес памяти, на который ссылается 5, содержит массив длиной 1. » Я не думаю, что «иногда переменные являются значениями, иногда переменными являются что-то другое», дает понять новичкам, что происходит. –

+0

Существует принципиальное различие между примитивными типами и типами объектов. Java-разработчик не будет очень далеко, если они не поймут эту разницу. –

-1

Ваш вопрос имеет ответ

INT является основным типом данных, и они передаются по значению, а не ссылки, так что значение остается неизменным :)

Смежные вопросы