Как использовать Pass by Value в Java - PullRequest
1 голос
/ 08 июня 2011
public class Test {

        public void Receiving (int var)
        {
          var = var + 2;
        }

        public static void main(String [] args)
        {
          int passing = 3;

          Receiving (passing);

          System.out.println("The value of passing is: " +passing);
        }    
    }

Когда я скомпилировал этот код ... я получил эту ошибку.

Test.java:12: non-static method Receiving(int) cannot be referenced from a static context
  Receiving (passing);
  ^

Теперь, когда я изменил свой метод Receiving на static, вывод был ....

The value of passing is: 3

Теперь, как я могу передать значение 3 в метод Receiving, чтобы вывод 5 выводился на консоль.

Ответы [ 10 ]

6 голосов
/ 08 июня 2011

Это обычно невозможно в Java, потому что примитивные типы всегда передаются по значению, а не по ссылке. Даже если вы используете класс-оболочку Integer вместо int, вы не сможете изменить это, поскольку Integer является неизменным.

Однако вы можете использовать этот трюк:

public class Test {

    // static is necessary, as you already found out
    public static void Receiving (int[] var)
    {
      var[0] = var[0] + 2;
    }

    public static void main(String [] args)
    {
      int[] passing = new int[] {3};
      Receiving (passing);
      System.out.println("The value of passing is: " +passing[0]);
    }    
}
5 голосов
/ 08 июня 2011

Это не будет передача по значению , это будет передача по ссылке !Передача по значению фактически означает, что метод работает с копией исходной переменной.(См. http://en.wikipedia.org/wiki/Evaluation_strategy). Java всегда передается по значению.

Для примитивных типов (например, int, float и т. Д.), Если вы хотите, чтобы входное значение изменялось какметод, вы можете просто вернуть его:

public static int Receiving(int var) {
    return var + 2;
}

...

passing = Receiving(passing);
3 голосов
/ 08 июня 2011

Теперь, как я могу передать значение 3 в Прием метода так, чтобы вывод 5 печатается в консоли.

Вы можете обернуть целое число так, чтобы оно было передано как ссылка:

public class Test {

    class Wrapper {
        int var;

        Wrapper(int val) {
            var = val;
        }
    }

    public void Receiving(Wrapper w) {
        w.var = w.var + 2;
    }

    public static void main(String[] args) {
        Test test = new Test();
        Wrapper passing = test.new Wrapper(3);
        test.Receiving(passing);
        System.out.println("The value of passing is: " + passing.var);
    }
}
3 голосов
/ 08 июня 2011

Java передается по значению, но вы должны понимать, что передано: это ссылка на объект или значение, а не сам объект или значение. Вы не можете изменить эту ссылку, но вы можете изменить состояние объекта, на который она указывает (пока он изменчив).

, поэтому вы никогда не увидите вывод «5» в вашей консоли. Это не так, как работает Java. JVM уже дала понять.

1 голос
/ 08 июня 2011

Невозможно сделать это с помощью «int» - в Java есть только «передача по значению».Тем не менее, можно легко смоделировать с AtomicInteger:

static void test(AtomicInteger i)
{
    i.addAndGet(2);
}

public static void main(String[] args) throws IOException
{
    AtomicInteger i = new AtomicInteger(3);
    test(i);
    System.out.println(i);
}
0 голосов
/ 08 июня 2011

То, что другие сказали выше, совершенно верно. Но если вы просто хотите получить 5 в качестве конечного результата, есть множество способов добиться этого. Я разместил ниже один из них.

public class NewClass {

     static int passing = 3;

    public static void Receiving (int var)
    {
      var = var + 2;
      passing = var;
    }

    public static void main(String [] args)
    {

      Receiving (passing);

      System.out.println("The value of passing is: " +passing);
    }

}

Я знаю, что это не очень хороший подход, но я чувствовал, что вы были одержимы получением 5 печатей ....

0 голосов
/ 08 июня 2011

Передача по ссылке невозможна в Java, и объекты вообще не передаются: Статья о передаче

Однако вы можете

  1. Использоватьвозвратите значение в вашей функции и используйте это значение в вашей основной программе
  2. Объявите статическое значение вверху.Тогда ваше значение будет охватывать всю программу, но вы не уверены, что хотите
0 голосов
/ 08 июня 2011

Тип примитива передается по значению. На объекты Java всегда ссылаются, и их ссылка всегда передается по значению.

Что касается статической ошибки, существует два способа ее устранения:

  1. Марка receiving static или:
  2. создайте Test объект и вызовите receiving.

Пример:

Test test = new Test();
test.Receiving(passing);

Чтобы перейти по ссылке, вам нужно будет передать ссылку на объект методу (из которого java передаст ссылку по значению) и выполнить вычисление оттуда. Подойдет массив int или AtomicInteger.

0 голосов
/ 08 июня 2011

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

public static int receiving (int var) {
    return var + 2;
}

public static void main(String... args){
    int passing = 3;
    // its clear passing can be changed.
    passing = receiving(passing); 
    System.out.println("The value of passing is: " +passing);
}   
0 голосов
/ 08 июня 2011

Нестатическая функция-член может быть вызвана только для экземпляра объекта.Он не может быть вызван «сам по себе».

У вас есть два варианта:

  1. make Receiving static;
  2. создать экземпляр Test в main и вызовите test.Receiving(3).

В любом случае, var будет передано в функцию по значению, поэтому main не увидит измененное значение.Чтобы обойти это, у вас есть несколько вариантов, которые включают:

  1. превращение var в одноэлементный массив,
  2. с использованием AtomicInteger (на самом деле он не предназначен для этого, но я часто вижу, что он используется таким образом).
...