zoukankan      html  css  js  c++  java
  • java基础:所有参数皆是按值参数

    c#中对于参数的传递,有二种处理方式,默认情况下:值类型的参数,按值传递(即:方法体内的参数是原值的副本);引用类型的参数,"加ref关键字后“,按引用传递(即:方法体内的参数,是对象的指针引用,在方法体内修改了对象的属性,方法调用完成后,这种变化也会保持下去).

    java虽然也是OO语言,但是这一点有很大不同,不管是“值”类型的简单参数(比如:int),还是“引用”类型的对象参数(比如:Object),参数永远是按值传递(参数永远是原值的副本)。只不过,对于int型的简单参数,比如:5,副本也是5,相当于在内存又开辟一块空间,存储5这个值,但这二个5完全不相关联。而对于对象参数(比如:Object),参数副本应理解成对象指针引用“地址值”的副本,比如:原Object对象在内存中的指针地址为OX0001,则参数为OX0001的另一个副本,因为这二个地址值相同,所以在大多数情况下,方法体内,通过指针地址定位到的对象是同一个,即:方法体内修改对象的属性,该对象就被永远修改了,即使方法调用完成,这种修改的结果也会永远保存下去。这给很多java初学者造成java中参数有按引用传递的错觉

    看下面的示例:

    先定义一个测试用的Person类

     1 package com.cnblogs.yjmyzz.test;
     2 
     3 public class Person {
     4     
     5     public Person(){}
     6 
     7     private String name;
     8 
     9     public String getName() {
    10         return name;
    11     }
    12 
    13     public void setName(String name) {
    14         this.name = name;
    15     }
    16 
    17     public String toString() {
    18         return "name:" + name;
    19     }
    20 
    21 }
    View Code

    然后来一个单元测试

     1     @Test
     2     public void testPerson1() {
     3 
     4         Person p1 = new Person();
     5         p1.setName("aaa");
     6         System.out.println(p1); // aaa
     7         System.out.println();
     8 
     9         changePerson1(p1);// xxx
    10         System.out.println(p1);// xxx
    11 
    12     }
    13     
    14     void changePerson1(Person p) {
    15         p.setName("xxx");
    16         System.out.println(p);
    17         System.out.println();
    18     }
    View Code

    运行结果:

    name:aaa

    name:xxx

    name:xxx

    如上图所示,这种情况很好理解,p1,p因为值相同,所以根据这个地址值,寻址找到的对象是同一个,改p.name值与改p1.name没什么分别

    再来一个版本:

     1 @Test
     2     public void testPerson2() throws InstantiationException,
     3             IllegalAccessException {
     4 
     5         Person p1 = new Person();
     6         p1.setName("aaa");
     7         System.out.println(p1); // aaa
     8         System.out.println();
     9 
    10         changePerson2(p1);// yyy
    11         System.out.println(p1);// xxx
    12     }
    13 
    14 
    15 
    16     void changePerson2(Person p) throws InstantiationException,
    17             IllegalAccessException {
    18         Person newPerson = Person.class.newInstance();
    19         newPerson.setName("yyy");
    20 
    21         p = newPerson;
    22 
    23         System.out.println(p);
    24         System.out.println();
    25     }
    View Code

    运行结果:

    name:aaa

    name:yyy

    name:aaa

    如上图,刚开始P1,P值相同,但是在ChangePerson2内部,又new了一个Person的新实例:newPerson,修改newPerson.Name,并不会影响P1和P,在最后,将newPerson赋值给p,注意:p只是p1的地址值副本,所以虽然p与newPerson最终指向一样了,但是并不会影响原值p1,所以方法调用完成后,p1.name还是原来的值

  • 相关阅读:
    Spring-----aop
    Activity的四种launchMode《转》
    解决gradle /Users/xxxx/Documents/workspace/fontmanager/.gradle/2.2.1/taskArtifacts/cache.properties (No such file or directory)报错办法
    Mac删除JDK
    Mac OSX Java 编译时乱码问题
    android中出现Error retrieving parent for item: No resource found that matches the Theme.AppCompat.Light
    使用AndroidStudio报错:INSTALL_FAILED_UPDATE_INCOMPATIBLE
    Java 类库和常用类库
    (斐波那契总结)Write a method to generate the nth Fibonacci number (CC150 8.1)
    各种排序学习归纳总结(Java)
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/4044985.html
Copyright © 2011-2022 走看看