值传递与引用传递

摘抄自威哥视频

例一:值传递(说白了,就是内容复制,或者说内容的副本)

public class ValueDemo{
    public static void main(String[] args){
        int x = 10;
        method(x);
        System.out.println("x="+x);
    }
    public static void method(int mx){
        mx = 20;
    }
}

例二:下面三个都是引用传递

package sunjava;

public class RefDemo2{
    public static void main(String[] args){
        String name = "小白";
        method(name);
        System.out.println("name="+name);
    }
    public static void method(String sname){
        sname = "小红";
    }
}

name=小白

例三:引用传递(说白了,就是地址传递,指向了同一个地址。栈内寸两个变量存储的是同一个地址。)

package sunjava;
public class RefDemo1{
    public static void main(String[] args){
        Cat c  = new Cat();
        method(c);
        System.out.println("Cat age = "+c.age);
    }
    public static void method(Cat cat){
        cat.age = 5;
    }
}
class Cat{
     int age = 2;//省略封装
}

5

例四:字符串特例

package sunjava;
public class RefDemo3{
    public static void main(String[] args){
        Cat c  = new Cat();
        method(c) ;
        System.out.println("Cat name= "+c.name) ;
    }
    public static void method(Cat cat){
        cat.name = "小黑";
    }
}
class Cat{
     String name = "小白";   //省略封装
}

Cat name= 小黑

总结:
1、每次new一个对象,就是在堆内存当中开辟一个新的空间。【无论以前是否有重复,如string1=new String(“helloworld”),如例五的string2和string4是false】

2、例四的 String name = "小白"; 字符串也是一个新的对象。

3、一个字符串就是一个对象

 例六:==(比较地址,就是指针的地址)与euals(比较内容,就是指针指向的内容)

public class String_test {     
    public static void main(String[] args) { 
        String str1 = "hello world"; 
        String str2 = new String("hello world"); 
        String str3 = "hello world"; 
        String str4 = new String("hello world");           
        System.out.println(str1==str2); 
        System.out.println(str1==str3); 
        System.out.println(str2==str4); 
        System.out.println(str2.equals(str4));//上面是地址,所以false,这里是内容 true 
   /*  上面的结果为 
    * ---------------
    *   false
        true
        false
        true*/
   //     1. 下面这段代码的输出结果是什么?

      String a = "hello2"; 
      String b = "hello" + 2;
      System.out.println((a == b));

      //  输出结果为:true。原因很简单,"hello"+2在编译期间就已经被优化成"hello2",因此在运行期间,变量a和变量b指向的是同一个对象。

    //  2.下面这段代码的输出结果是什么?

      String a2 = "hello2"; 
      String b2 = "hello";      
      String c2 = b2 + 2;     
      System.out.println((a2 == c2));

    //    输出结果为:false。由于有符号引用的存在,所以  String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象

    } 
}

例七:一个字符串就是一个对象。如果没有找到相同的,就新建一个对象,指向原来的内容一把x,指向新的。

public class sadf {
    public static void changeStr(String str)
    {
        str="welcome";    
        System.out.println(str);        
    }
    public static void main(String[] args)
    {
        String str="1234";
        changeStr(str);
        System.out.println(str);        
    }

}
/*
 * 结果为
 *----------------* 
 * welcome
   1234
*/

 例八: 

public class sdf {
    public static void main(String[] args)
    {
        String str=new String("world");
        char ch[]={'H','e','l','l','o'};
        change(str,ch);
        System.out.println(str+"and");        
        System.out.println(ch);        
    }
    public static void change(String str,char ch[])//数组的本质传递的是地址
    {
        str="Change";//这个上面的例题同
        ch[0]='c';
        
    }

}
/*
 * 结果为
 *----------------* 
worldand
cello

*/

 从上面这个例子我们知道,字符串是值传递,而数组是句柄传递(c++,也就是指针)

c++的竟然也是一样的结果

#include <iostream>

using namespace std;
void Change(char *str2,char *ch)
{
    str2="Change";
    ch[0]='C';    
}
int main()
{
    char *str2="world";
    char ch[]={'H','e','l','l','o'};
    Change(str2,ch);
    cout <<str2;
    cout << "and" <<endl;
    cout << ch << endl;    
    return 0;    
    
}

 c++灵活的地方在于字符串中可以传地址(强制传入地址) 而java 和c#确不可以做到这一点,而只能用返回值的方法来实现。

如下,修改版的就可以

#include <iostream>

using namespace std;
void Change(char **str2,char *ch)
{
    *str2="Change";
    ch[0]='C';    
}
int main()
{
    char *str2="world";
    char ch[]={'H','e','l','l','o'};
    Change(&str2,ch);
    cout <<str2;
    cout << "and" <<endl;
    cout << ch <<endl;    
    return 0;    
    
}

参考文章:http://www.cnblogs.com/bluewelkin/p/4080767.html 

例9:

public class sdf {
    public static void main(String[] args)
    {
        String str=new String("world");
        char ch[]={'H','e','l','l','o'};
        change(str,ch);
        System.out.println(str+"and");        
        System.out.println(ch);        
    }
    public static void change(String str,char ch[])//数组的本质传递的是地址
    {
        str="Change";//这个上面的例题同
//    /    ch[0]='c';
    ch=new char[]{'c','e','l','l','0'};        //相当于新备了一把钥匙,新建了一个仓库,但没有改变原来的值。
    }
}
/*
 * 结果为
 *----------------* 
worldand
Hello

*/

 例十:

public class asdf{
 public static void main(String[] args){
         String foo="blue";
     String bar=foo;
      foo="green";
     System.out.println(bar);
     System.out.println(foo);
         }
    }

/*结果为:
blue
green*/

 例十一:

public class asdf{
 public static void main(String[] args){
     String a = "ABCD";
     String b = a.toLowerCase();
    String c= b.replace('a', 'd');//这样替换新建一个才有效
     b.replace('b','c');// 这样替换还是原来的
     System.out.println(b);
     System.out.println(c);
         }
    }

/*结果为:
abcd
dbcd

*/
原文地址:https://www.cnblogs.com/bluewelkin/p/4091881.html