Java 应用程序中的参数传递



在继续讨论之前,定义 按值传递和 按引用传递这两个术语是重要的。 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。 按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。

关于 Java 应用程序中参数传递的某些混淆源于这样一个事实:许多程序员都是从 C++ 编程转向 Java 编程的。C++ 既包含非引用类型,又包含引用类型,并分别按值和按引用传递它们。Java 编程语言有基本类型和对象引用;因此,认为 Java 应用程序像 C++ 那样对基本类型使用按值传递,而对引用使用按引用传递是符合逻辑的。毕竟您会这么想,如果正在传递一个引用,则它一定是 按引用传递的。很容易就会相信这一点,实际上有一段时间我也相信是这样,但这不正确。

在 C++ 和 Java 应用程序中,当传递给函数的参数不是引用时,传递的都是该值的一个副本(按值传递)。区别在于引用。在 C++ 中当传递给函数的参数是引用时,您传递的就是这个引用,或者内存地址(按引用传递)。在 Java 应用程序中,当对象引用是传递给方法的一个参数时,您传递的是该引用的一个副本(按值传递),而不是引用本身。请注意,调用方法的对象引用和副本都指向同一个对象。这是一个重要区别。Java 应用程序在传递不同类型的参数时,其作法与 C++ 并无不同。Java 应用程序按值传递所有参数,这样就制作所有参数的副本,而不管它们的类型。

class Test
{
  
public static void main(String args[])
  
{
    
int val;
    StringBuffer sb1, sb2;
    val 
= 10;
    sb1 
= new StringBuffer("apples");
    sb2 
= new StringBuffer("pears");
    System.out.println(
"val is " + val);
    System.out.println(
"sb1 is " + sb1);
    System.out.println(
"sb2 is " + sb2);
    System.out.println(
"");
    System.out.println(
"calling modify");
    
//按值传递所有参数
    modify(val, sb1, sb2);
    System.out.println(
"returned from modify");
    System.out.println(
"");
    System.out.println(
"val is " + val);
    System.out.println(
"sb1 is " + sb1);
    System.out.println(
"sb2 is " + sb2);
  }

  
public static void modify(int a, StringBuffer r1,
                            StringBuffer r2)
  
{
      System.out.println(
"in modify...");
      a 
= 0;
      r1 
= null;  //1
      r2.append(" taste good");
      System.out.println(
"a is " + a);
      System.out.println(
"r1 is " + r1);
      System.out.println(
"r2 is " + r2);
  }

}

Java 应用程序的输出
val is 10
sb1 is apples
sb2 is pears
calling modify
in modify...
a is 0
r1 is null
r2 is pears taste good
returned from modify
val is 10
sb1 is apples
sb2 is pears taste good

编写一个交换方法
class Swap
{
  
public static void main(String args[])
  
{
    Integer a, b;
    a 
= new Integer(10);
    b 
= new Integer(50);
    System.out.println(
"before swap...");
    System.out.println(
"a is " + a);
    System.out.println(
"b is " + b);
    swap(a, b);
    System.out.println(
"after swap...");
    System.out.println(
"a is " + a);
    System.out.println(
"b is " + b);
  }

  
public static void swap(Integer a, Integer b)
  
{
    Integer temp 
= a;
    a 
= b;
    b 
= temp;
  }

}

因为 Java 应用程序按值传递所有参数,所以这段代码不会正常工作
before swap...
a is 10
b is 50
after swap...
a is 10
b is 50
The Java Programming Language,Second Edition的作者,Ken Arnold 和 James Gosling 在 2.6.1 节中说得最好:“在 Java 中只有一种参数传递模式 -- 按值传递 -- 这有助于使事情保持简单。”

Hashtable真的能存储对象吗?
import java.util.*;

public class HashtableAdd {
    
public static void main(String[] args) {
        Hashtable ht 
= new Hashtable();
        StringBuffer sb 
= new StringBuffer();
        sb.append(
"abc,");
        ht.put(
"1", sb);
        sb.append(
"def,");
        ht.put(
"2", sb);
        sb.append(
"mno,");
        ht.put(
"3", sb);
        sb.append(
"xyz.");
        ht.put(
"4", sb);

        
int numObj = 0;
        Enumeration it 
= ht.elements();
        
while (it.hasMoreElements()) {
            System.out.print(
"get StringBufffer " + (++numObj) + " from Hashtable: ");
            System.out.println(it.nextElement());
        }

    }

}


把对象时作为入口参数传给函数,实质上是传递了对象的引用,向Hashtable传递 StringBuffer对象也是只传递了这个StringBuffer对象的引用!每一次向Hashtable表中put一次 StringBuffer,并没有生成新的StringBuffer对象,只是在Hashtable表中又放入了一个指向同一StringBuffer对象的引用而已。这条原则对与Hashtable相似的Vector, List, Map, Set等都是一样的。
OUTPUT:
get StringBufffer 1 from Hashtable: abc,def,mno,xyz.
get StringBufffer 2 from Hashtable: abc,def,mno,xyz.
get StringBufffer 3 from Hashtable: abc,def,mno,xyz.
get StringBufffer 4 from Hashtable: abc,def,mno,xyz.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值