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接口进行调用的,我不太清楚是否属于远程调用。以后确定了再来更新。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值