Java 参数传递方式

本文转自 http://www.jianshu.com/p/8fa4dceb6fdc
Java方法传参方式记住了两点。基本上不会犯错误。
1. 方法内修改基础数据类型(数字类型或布尔类型)不会改变方法外的参数;
2. 方法内修改对象(包含数组)状态会同步修改方法方法外的参数。


程序片段1来验证第一点:
public static void main(String[] args) {
    Integer a = 5;
    System.out.println("入栈前 a = " + a);
    calc(a);
    System.out.println("出栈后 a = " + a);    
 }
private static void calc(Integer a) {
    a = a * 3;
    System.out.println("栈内计算 a = " + a);
}
程序的运行结果为:
入栈前 a = 5
栈内计算 a = 15
出栈后 a = 5

程序片段2来验证第二点
public static void main(String[] args) {
    Stu tom = new Stu(30, "tom");
    System.out.println("入栈前 tom = " + tom);
    doubleScore(tom);
    System.out.println("出栈后 tom = " + tom);

}

private static void doubleScore(Stu tom) {
    tom.score = tom.score * 2;
    System.out.println("栈内计算 tom = " + tom);
}

private static class Stu {
    String name;
    int score;
    public Stu(int score, String name) {
        this.score = score;
        this.name = name;
    }
    @Override
    public String toString() {
        return "[ name='" + name + '\'' + ", score=" + score + ']';
    }
}
片段2的运行结果为:
入栈前 tom = [ name='tom', score=30]
栈内计算 tom = [ name='tom', score=60]
出栈后 tom = [ name='tom', score=60]

从两段程序的结果看,片段1的基础数据参数用值传递来解释的通;片段2的对象参数用引用传递也行的通。

究竟参数传递采用哪种方式呢,特地翻了 Java编程思想第四版 第12章 传递和返回对象 中给出了解释,Java中所有参数或自变量都是通过句柄的方式传递的,向方法中传递一个参数时,实际上传递的只是指向外部对象的一个句柄。

看清楚了吗,人家根本不关心什么值传递、引用传递,实际上问题的关键是怎么理解 句柄

  • Java按值传递任何东西。句柄当做指针,传递对象就是拷贝对象的地址值,参数也指向该对象,方法内对象状态改外部对象也会改变;基础数据类型就更明显,基础数据传入方法会得到一个数据的副本,所以一切传参都是按值传递。
  • Java主要按值传递,但对象却是引用传递。句柄看做对象的一个“别名”,由于对象传入方法没有获得一个本地副本,所以对象传递显然不是值传递,而是引用传递。
    句柄 的理解不同带来了不同的结果,原书的作者直接回避了这个问题,也许java的设计者压根没有考虑这个问题,才会后面的争议。

还有一点一定要记住,记为第三点:
  1. 方法不能改变对象参数的引用
程序片段3来验证第3点:
public static void main(String[] args) {
    Stu tom = new Stu(30, "tom");
    System.out.println("入栈前 tom = " + tom);
    convert(tom);
    System.out.println("出栈后 tom = " + tom);
}
private static void convert(Stu tom) {
    tom = new Stu(50, "jack");
    System.out.println("栈内计算 tom = " + tom);
}
程序片段3来运行结果:
入栈前 tom = [ name='tom', score=30]
栈内计算 tom = [ name='jack', score=50]
出栈后 tom = [ name='tom', score=30]

总结

不管一切按值传递,还是主要按值传递,从这三个特点来讲都解释的通,没必要为概念纠结,明白特性才是关键!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值