обмен объектами в java

Я изучил, что java передается по ссылке, но когда я выполняю следующий код, строки не меняются местами в основном методе почему?

static void swap(String s1, String s2){
    String temp = s1;
    s1=s2;
    s2=temp;
}

public static void main(String[] args) {
    String s1 = "Hello", s2 = "world";
    swap(s1, s2);
    System.out.println(s1 + s2);
}

8 ответов


вы изучили неправильные источники. Java передается по значению. здесь еще один источник, который вы можете изучать. И от здесь вы можете найти обсуждение о примере, похожем на ваш.


1. прежде всего,Java is pass by Value.(ie пройти мимо Copy).

2. вы мимо reference не the объект методу.

например:

public class Test{

        private String x;

            public void go(String s){

                this.x = s;

           }

         public static void main(String[] args){

                  Test t = new Test();

                  String a = new String("Bye");

                  t.go(a);


             }
      }

на выше код не для того, чтобы показать, как выполняется замена, но чтобы сделать важный момент видимым.

  • , когда go(String s) метод вызывается путем передачи аргумента "a", который является Object reference variable типа String к параметру "s", который также является Object reference variable типа String,это просто ссылка, которая передается значением / копией.

  • любой изменения, внесенные на reference будет влиять на объект String в куче, а не the reference.


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

попробуйте это:

static void reverse(StringBuilder builder) {
    builder.reverse();
}

public static void main(String[] args) {
    StringBuilder builder = new StringBuilder("hello");
    System.out.println(builder);
    reverse(builder);
    System.out.println(builder);
}

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

static void swap(StringBuilder builder) {
    builder = null;
}

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


EDIT:

@dasblinkenlight показывает, как использовать массивы для замены двух строк, и вот пример использования класса wrapper:

public class WrapperString
{
    public String text;

    public WrapperString(String text){this.text = text}

    @Override
    public String toString(){return text;}
}

public static void swap(WrapperString a, WrapperString b)
{
    String temp = a.text;
    a.text = b.text;
    b.text = temp;
}

public static void main(String[] args)
{
    WrapperString s1 = new WrapperString("Hello");
    WrapperString s2 = new WrapperString("World");

    swap(s1, s2);
    System.out.println(s1.text + s2.text);
    // or System.out.println(s1 + s2); since we've already overridden toString()
}

выход:

WorldHello

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

если вы передадите изменяемые объекты, однако, вы увидите, что изменения в них сделаны в swap отразится в оригинале:

public static void main(String[] args) {
    String a[] = {"hello", "world"};
    swap(a);
    System.out.println(a[0] + " " + a[1]);
}
static void swap(String[] a) {
    String t = a[0];
    a[0] = a[1];
    a[1] = t;
}

это работает, потому что array is mutable (т. е. изменения могут быть сделаны его состояние), а также потому, что ссылка на исходный объект передается вызываемой функции (по значению). Когда swap изменяет содержимое своего a содержание a в вызывающем объекте также изменяется, потому что это тот же объект.


public static void swap(SwapDate[] t)
    {
     SwapDate temp;;
      temp=t[0];
       t[0]=t[1];
       t[1]=temp;
    }




       public static void main(String args[])throws Exception{

          SwapDate t[]=new SwapDate[5];
           t[0]=new SwapDate(20,8,2015);
           t[1]=new SwapDate(8,8,2015);

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           swap(t);
           System.out.println("After Swap");

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           }

Java строго передается по значению.

давайте изменить код, как показано ниже, с точки зрения объяснения

static void swap(String str1, String str2){
String temp = str1;
str1=str2;
str2=temp;
}

public static void main(String[] args) {
String s1 = "Hello", s2 = "world";
swap(s1, s2);
System.out.println(s1 + s2);

}

S1 и S2-это ссылки, содержащие адрес строкового объекта. Например: S1=123, S2= 234

при вызове метода swap создается копия S1 и S2, которая будет назначена str1 и str2.

который будет str1=123 и str2=234.

Swap метод будет только поменять значения, присутствующие в str1 и str2. (str1=234 str2=123), тогда как S1 и S2 по-прежнему указывают на одно и то же место памяти.

это причина, по которой своп не отражается в основном методе.


мы можем поменять местами объекты. Это так просто.Просто нужно использовать один фиктивный объект для замены двух объектов.

пример приведен ниже:

    Employee e1=new Employee();
    Employee e2=new Employee();
    e1.setName("e1");
    e2.setName("e2");   
    System.out.println(e1);
    System.out.println(e2);
    Employee temp= new Employee();
    temp=e1;
    e1=e2;
    e2=temp;