zoukankan      html  css  js  c++  java
  • java — 值传递和引用传递

      

      在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 应用程序是按值传递对象引用的

      Java 应用程序中的变量可以为以下两种类型之一:引用类型或基本类型。当作为参数传递给一个方法时,处理这两种类型的方式是相同的。两种类型都是按值传递的;没有一种按引用传递。

      java实际上只有值传递,没有真正意义上的引用传递。

      按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。

      按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。

        1、对象是按引用传递的;
      2、Java 应用程序有且仅有的一种参数传递机制,即按值传递;
      3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本;
      4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。

    ①引用传递

    package quoteDemo;
    
    public class test1 {
    	public static void main(String[] args)
    	{
    		StringBuffer s1 = new StringBuffer("good");
    		StringBuffer s2 = s1;
    		s2.append(" morning");
    		System.out.println(s1);
    	}
    
    }
    

    在上述程序的这一句:

    StringBuffer s2 = s1;
    

      会使得对象s1和对象s2指向内存中相同的地址,因而会指向同一个对象。

    运行的结果:

    good morning
    

      在这里进行的是引用传递

      进行对象赋值操作的时候,传递的是对象的引用,因此对象是引用传递,但其实这里的传递对象实际上是值传递。因为对象就是一个指针,这个赋值是指针之间的赋值,在java中将这种对象的传递称为引用传递

    ②值传递

    package quoteDemo;
    
    public class test2 {
    	public static void main(String[] args)
    	{
    		int i1 = 5;
    		int i2 = i1;
    		i2 = 6;
    		System.out.println("i1 = " + i1);
    		System.out.println("i2 = " + i2);
    	}
    
    }
    

    输出结果:

    i1 = 5
    i2 = 6
    

      原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为下一个问题:Java 应用程序有且仅有的一种参数传递机制,即按值传递。

    对于这一句:

    i2 = i1;
    

      获取的是副本,所以后来的操作是对副本的操作,而不是对i1的操作。

    ③较为复杂的引用传递

    package quoteDemo;
    
    class test12
    {
    	public static void main(String[] args)
    	{
    	StringBuffer s= new StringBuffer("good");
    	StringBuffer s2=new StringBuffer("bad");
    	test(s,s2);
    	System.out.println(s);//9
    	System.out.println(s2);//10
    	}
    	static void test(StringBuffer s,StringBuffer s2) 
    	{
    		System.out.println(s);//1
    		System.out.println(s2);//2
    		s2=s;//3
    		s=new StringBuffer("new");//4
    		//s2=s;//3
    		System.out.println(s);//5
    		System.out.println(s2);//6
    		s.append("hah");//7
    		s2.append("hah");//8
    		//System.out.println(s2);
    	}
    }

     输出的结果:

    good
    bad
    new
    good
    goodhah
    bad
    

      注意在test函数中,前两行输出s和s2的时候,仍然是原始的s和s2的值,但执行 s2 = s 的时候,s2指向的是原始的s,而接下来的s = new StringBuffer("new")这一句的时候,s就会指向局部的"new",然后输出的s和s2分别是new和good(因为s2实际指向原来的s),所以之后执行的s2.append("hah")实际上是原始的s的后边加上了"hah"。

    稍作改变,先让s指向新的字符串,然后再调用s2 = s。

    package quoteDemo;
    
    class test12
    {
    	public static void main(String[] args)
    	{
    	StringBuffer s= new StringBuffer("good");
    	StringBuffer s2=new StringBuffer("bad");
    	test(s,s2);
    	System.out.println(s);//9
    	System.out.println(s2);//10
    	}
    	static void test(StringBuffer s,StringBuffer s2) 
    	{
    		System.out.println(s);//1
    		System.out.println(s2);//2
    		//s2=s;//3
    		s=new StringBuffer("new");//4
    		s2=s;//3
    		System.out.println(s);//5
    		System.out.println(s2);//6
    		s.append("hah");//7
    		s2.append("hah");//8
    		System.out.println(s2);
    	}
    }
    

    输出的结果:

    good
    bad
    new
    new
    newhahhah
    good
    bad
    

      

     其他的例子:

    package quoteDemo;
    
    class Message
    {
    	private int num = 10;
    	public Message(int num)
    	{
    		this.num = num;
    	}
    	
    	public void setNum(int num)
    	{
    		this.num = num;
    	}
    	
    	public int getNum()
    	{
    		return num;
    	}
    	
    }
    
    public class TestDemo 
    {
    	public static void main(String[] args)
    	{
    		Message msg = new Message(30);
    		fun(msg);
    		System.out.println(msg.getNum());
    	}
    	public static void fun(Message temp)
    	{
    		temp.setNum(100);
    	}
    }
    

    实际的执行过程如下图所示:

    Java 应用程序有且仅有的一种参数传递机制,即按值传递。

     

    能让一个男孩子热血的,不仅有梦想,还有姑娘。
  • 相关阅读:
    图像处理之霍夫变换(直线检測算法)
    Linux makefile 教程 很具体,且易懂
    POJ 2001 Shortest Prefixes(字典树)
    android performClick使用
    Java工厂模式
    C#异步调用
    答读者问(5):有关数学对程序猿的作用、研发工作岗位要求和实习对找工作的影响等问题
    Android系统源码导入到eclipse
    开源项目与许可证
    Java实现第十届蓝桥杯矩形切割
  • 原文地址:https://www.cnblogs.com/Mr24/p/6539181.html
Copyright © 2011-2022 走看看