java参数传递

转载 2013年12月01日 20:39:25
值传递:表示方法接收的是调用者提供的值。

引用传递:表示方法接受的是调用者提供的变量地址。

Java总是值传递,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容。

--java核心技术 卷1 第八版 中文版-115页


搬运工

参考博文http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 
    答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。

Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。


    如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
    如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

public class ParamTest {
    public static void main(String[] args){
          /**
           * Test 1: Methods can't modify numeric parameters
           */
         System.out.println("Testing tripleValue:");
          double percent = 10;
          System.out.println("Before: percent=" + percent);
          tripleValue(percent);
          System.out.println("After: percent=" + percent);

          /**
           * Test 2: Methods can change the state of object parameters
           */
          System.out.println("\nTesting tripleSalary:");
          Employee harry = new Employee("Harry", 50000);
          System.out.println("Before: salary=" + harry.getSalary());
          tripleSalary(harry);
          System.out.println("After: salary=" + harry.getSalary());

          /**
           * Test 3: Methods can't attach new objects to object parameters
           */
          System.out.println("\nTesting swap:");
          Employee a = new Employee("Alice", 70000);
          Employee b = new Employee("Bob", 60000);
          System.out.println("Before: a=" + a.getName());
          System.out.println("Before: b=" + b.getName());
          swap(a, b);
          System.out.println("After: a=" + a.getName());
          System.out.println("After: b=" + b.getName());
    }

    private static void swap(Employee x, Employee y) {
        Employee temp = x;
        x=y;
        y=temp;
        System.out.println("End of method: x=" + x.getName());
        System.out.println("End of method: y=" + y.getName());
    }

    private static void tripleSalary(Employee x) {
        x.raiseSalary(200);
        System.out.println("End of method: salary=" + x.getSalary());
    }

    private static void tripleValue(double x) {
        x=3*x;
        System.out.println("End of Method X= "+x);
    }
}

显示结果:

Testing tripleValue:
Before: percent=10.0
End of Method X= 30.0
After: percent=10.0

Testing tripleSalary:
Before: salary=50000.0
End of method: salary=150000.0
After: salary=150000.0

Testing swap:
Before: a=Alice
Before: b=Bob
End of method: x=Bob  //可见引用的副本进行了交换
End of method: y=Alice
After: a=Alice  //引用本身没有交换
After: b=Bob



参考博文:http://blog.sina.com.cn/s/blog_5dd380b90100bvel.html

网络上有太多关于JAVA参数传递是传值还是传引用的讨论,其实大多是概念不清,混淆视听。从程序运行的角度来看,参数传递,只有传值,从不传递其它的东西。只不过值的内容有可能是数据,也有可能是一个内存地址。

  Java中的数据类型有两大类,即基本类型(primitive types), 共有8种,包括int, short, long, byte, float, double, boolean, char,存在于栈(Stack)中。另一种暂称为对象类型,包括Integer, String, Double等相应基本数据类型的包装类,以及其他所有JAVA自带和用户自定义的类,这些类数据全部存在于堆中(Heap),如下图所示。

   对象类型的数据不同于基本类型的数据,我们所定义的对象变量并不是对象实例本身,而是对象的一个引用(reference)地址,该内存地址用来定位该对象实例在HEAP中的位置。对象实例本身和对象的引用分别保存在HEAP和STACK中,对象引用和对象实例之间的关系好比遥控器和电视机之间的关系,在房间走动的时候里,你只需拿着遥控器就可以控制电视机,而不必带着电视机。而且,即使没有电视机,遥控器也可以独立存在,也就是说你可以定义一个对象类型的变量,但是可以暂时不和一个对象实例关联。多个对象引用也可以指向同一个对象实例。

           Heap(堆)       Stack(栈)
 JVM中的功能            内存数据区                    内存指令区
 存储数据  对象实例  基本数据类型, 指令代码,常量,对象的引用地址
例子1:

public class Test {
public static void changeValue(int i) {
i=2;
System.out.println("during test: i = " + i);
}
public static void main(String[] args) {
int i = 1;
System.out.println("Before test: i = " + i);
changeValue(i);
System.out.println("After test: i = " + i);
}
}

运行结果:
Before test: i = 1
during test: i = 2
After test: i = 1
不难看出,虽然在 changeValue(int i)方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响。其内部原理是,main方法里的变量和changeValue方法的参数是两个不同的变量,以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法的,那么在方法里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。
例子2:

public class Test {
public static void test(StringBuffer str) {
str.append(", World!");
}
public static void main(String[] args) {
StringBuffer string = new StringBuffer("Hello");
test(string);
System.out.println(string);
}
}

运行结果:
Hello, World!
   在这个例子里,似乎变量string被“改变”了。但其实改变的并不是string变量本身,也就是说string保存的内存地址并没有被改变,改变的是它所指向的对象实例。内部原理是这样的,在main方法里定义了一个对象引用string,并且把它和一个对象实例关联new StringBuffer。方法调用的时候,string所保存的对象实例的内存地址传递给了test方法的对象引用参数str,这时就有两个对象引用变量指向同一个对象实例。这两个对象引用都可以对该对象实例进行操作,操作结果都有效,因此在test方法执行完之后,对象实例的内容已经被改变了,这个时候再通过main方法里的string引用去查看对象实例的内容,看到的就是改变之后的内容。
例子3:

public class Test {
public static void test(String str) {
str = "World";
}
public static void main(String[] args) {
String string = "Hello";
test(string);
System.out.println(string);
}
}

运行结果:
Hello。
这个结果和上面结果矛盾吗?一点也不矛盾。在这个例子中,参数传递过程和上个例子完全一样,但是在test方法里并不是对原来指向的对象实例进行操作,而是把str指向了另外一个对象实例,当然对原来的对象实例毫无影响。


Java只有一种参数传递机制------按值传递

Java中并没有传递引用这一说,只有一种参数传递机制,就是按值传递 首先,最主要要强调的一点就是,Java 应用程序有且仅有的一种参数传递机制,并没有传递引用这一说。造成这一误解,主要是因为有这么...
  • zlf4896
  • zlf4896
  • 2016年03月15日 17:42
  • 443

Java的参数传递到底是引用传递还是值传递

首先看一段代码:public static void main(String[] args) { Person a = new Person(23, "a"); Person b = ...
  • panyongcsd
  • panyongcsd
  • 2016年08月30日 17:14
  • 1844

Java基础(五)Java中的参数传递机制

通过前一篇文章的介绍,我们从整体上明白了,Java类中变量的差异性、不同变量在内存中的存储位置,以及变量的生命周期等。今天,我们来看一下Java中参数传递的机制。 形参:方法声明时包含的参数声明 ...
  • liu765023051
  • liu765023051
  • 2015年08月11日 16:02
  • 5390

Java方法中的参数传递方式

在Java语言中,参数传递时,一般存在两种参数传递的规则 1.按值传递(by value) 使用该方式传递的参数,参数原始的值不发生变化 适用范围:八种基本数据类型和...
  • u011499992
  • u011499992
  • 2015年08月04日 19:11
  • 1437

java 传递参数的两种方式

Java中没有指针,所以也没有引用传递了,仅仅有值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能   值传递:方法调用时,实...
  • maoyeqiu
  • maoyeqiu
  • 2015年10月19日 15:39
  • 15935

Java的方法的参数传递,值传递和引用传递还有String字符串传递

方法的参数传递 1、值传递  a) 方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。传到方法里的参数类型是基本数据类型的都叫值传递 2、引用传递 ...
  • wolf09311
  • wolf09311
  • 2014年11月11日 14:35
  • 4689

Java中函数参数的传递形式是值传递 还是引用传递

突然想到这个问题,不是很确定,然后查了一下资料,做一下总结.  1.什么是值传递,什么是引用传递 值传递是将需要传递的值作为一个副本传递出去,例如: int i = 5; in...
  • u010483016
  • u010483016
  • 2015年12月09日 20:06
  • 3722

JAVA参数没有引用传递,只有值传递

原文章地址:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的...
  • sunp823
  • sunp823
  • 2015年09月22日 20:59
  • 545

JAVA中方法参数的引用传递

JAVA中方法参数的引用传递 java中参数的传递有两种,分别是按值传递和按引用传递。按值传递不必多说,下面就说一下按引用传递。 当一个对象被当作参数传递到一个方法”,这就是所谓的按引用传递。...
  • u013366812
  • u013366812
  • 2016年07月29日 10:35
  • 2978

Java传递基本类型:值传递,对象作为参数:引用传递

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。 引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相...
  • dreamxiaowei
  • dreamxiaowei
  • 2017年02月25日 15:53
  • 2933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java参数传递
举报原因:
原因补充:

(最多只允许输入30个字)