zoukankan      html  css  js  c++  java
  • java参数与引用

    java参数与引用

    java参数与引用

    总所周知,java虽然没有引用的概念,但是java在传入参数时,实际传入的参数对象是外部对象的引用,也就是重新生成一个指向外部对象的对象,只不过这两个对象指向的是同一片内存对象而已 ,我们举例来说明参数和引用的关系,我们假定方法changeString为
            public void changeString(String a ){
                    a = new String("I am b!" );
                    System.out.println(a);
            }
           
    那么当如下调用changeString(String a )方法时
            String a = new String("I am a!" );
            changeString(a);
            ......
    java的做法实际等价于
            String a = new String("abc" );
            String b = a;
            changeString(b);
            ............
    也就是说在被调用方法内部,传入参数对象和外部对象是不同的对象;虽然两者指向的是同一个内存对象,但是很容易将两者的联系断开 ,比如我们可以用如下的方法来测试一下
            String a = new String("I am a!" );
            System.out.println(a);
            //调用changeString方法
            changeString(a);
            System.out.println(a);
           
            结果应该为
            I am a!;
            I am b!;
            I am a!;
    也 就是说外部对象a的值并没有改变,这是因为在changeString(String a )方法内部,参数对象a并不是外部对象a了(其实你如果把方法改成public void changeString(String b)这样更能理解参数对象b和外部对象a是两个对象了),参数对象a和外部对象a是两个对象,指向同一个内存对象new String("abc" ),但是在方法内部,当参数对象a被重新赋值时(a = new String("b" ))时,参数对象
    a被重新指向一个新的内存对象new String("I am b!" ),这样参数对象a和外部对象a断开了关系
    ,再没有任何联系了,因此外部对象a的值也不可能有什么变化。

       通过以上说明,你应该对参数和引用有所理解;说到这里,我们要注意变量的赋值,当使用"="为变量赋值时,一般都是为变量a重新指定一个新的内存对象,因此当用"只读对象 "做为参数时,外部对象的值安全的,这些对象和数据包括为
                    基本类型,比如int,char
                    只读对象,比如String,Integer等
       也就是说你不可能通过调用方法来试图改变原有对象的值,你能通过调用changeValue(int a,int b)来交换a和b的值么?
           

        如果某些时候你需要在方法内部改变原有对象的值怎么办,办法很简单,不要为参数对象指向新的内部对象,并在此基础上,调用参数对象的方法来改变内存对象,比如,我们考虑如下方法
            public void changeBufferValue(StringBuffer sb){
                    sb.append("I am b!");
            }
           
    如下调用
            StringBuffer a = new StringBuffer("I am a!");
            System.out.println(a.toString());
            changeBufferValue(a);
            System.out.println(a.toString());

    输入结果应该为
            I am a!
            I am a!I am b!

    如果方法写成
            public void changeBufferValue(StringBuffer sb){
                    sb = new StringBuffer("I am b!");
            }
    你应该知道结果是什么了吧!,因此当你期望方法内部能改变传入变量的值时,慎用"="号为参数对象重新赋值。


    1、对于原始数据类型,也就是int、 long、char之类的类型,是传值的,如果你在方法中修改了值,方法调用结束后,那个变量的值没用改变。
    2、对于对象类型,也就是Object的子类,如果你在方法中修改了它的成员的值,那个修改是生效的,方法调用结束后,它的成员是新的值,但是如果你把它指向一个其它的对象,方法调用结束后,原来对它的引用并没用指向新的对象。

    代码如下:
    public class Tester {
    public static void main(String[] args) {
    int primitive = 2;
    changePrimitive(primitive);
    //primitive的值依然是2
    MyClass myClass = new MyClass();
    changeObject(myClass);
    //myClass仍然指向的是执行changeObject之前的那个对象
    //但是myClass.i等于3了
    }

    public static void changePrimitive(int primitive) {
    primitive = 3;
    }

    public static void changeObject(MyClass myClass) {
    myClass.i = 3;
    myClass = new MyClass();
    }
    }

    class MyClass {
    int i;
    }

    对于远程调用,无论是什么类型,调用结束后,传入的参数和以前没用任何变化(当然前途是直接调用远程方法,如果中间经过其它的Proxy类或者 Facade类,不能保证那些类对对象没用修改)。至于是通过Locale接口进行调用的,我不太清楚是否属于远程调用。以后确定了再来更新。

     
  • 相关阅读:
    [XJOI]noip43 T2多人背包
    Codeforces Round #198 (Div. 2)E题解
    [XJOI]noip40 T2统计方案
    Codeforces Round #198 (Div. 2)C,D题解
    Codeforces Round #198 (Div. 2)A,B题解
    9.19[XJOI] NOIP训练37
    9.18[XJOI] NOIP训练36
    kmp算法详解
    [模板系列] AC自动姬
    luogu1967[NOIP2013D1T3] 货车运输 (最大生成树+LCA)
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/1994699.html
Copyright © 2011-2022 走看看