欢迎转载,转载请声明出处!
-----------------------------------------
前言:

java语言中,參数的传递仅仅有一种机制。那就是值传递

举例:
以下将通过几个样例来说明java中的參数传递机制,这些样例基本涵盖了全部參数传递的情况。

1.基本数据类型:
public static void testBase(int i)
{
i = 2;
}

測试:

int i = 10;
System.out.println(i);//10
testBase(i);
System.out.println(i); //10

结果当然非常显然都是10。由于基本数据类型传递的是值的一份拷贝(副本),对副本操作不影响原始值。


2.对象:
    2.1.对參数又一次赋值:
public static void testObj(Object o)
{
o = new Object();
}

測试:

Object o = new Object();
System.out.println(o);// java.lang.Object@1ff61bcf
testObj(o);
System.out.println(o);//java.lang.Object@1ff61bcf

方法中的參数仅仅是原始对象的一份拷贝,更准确的讲是地址的一份拷贝,故而对其进行又一次赋值并不会影响原始对象。


 
2.2.改变对象内部数据:
public class S
{
private Object o = new Object();
private int i = 2; public Object getO()
{
return o;
}
public void setO(Object o)
{
this.o = o;
}
public int getI()
{
return i;
}
public void setI(int i)
{
this.i = i;
}
}

測试方法:

public static void testA(S s)
{
s.setI(100);
s.setO(new Object());
}

測试:

S s = new S();
System.out.println(s.getI()+","+s.getO());// 2,java.lang.Object@11b75be2
testA(s);
System.out.println(s.getI()+","+s.getO());//100,java.lang.Object@1cf15b84

由于对象作为參数传递的是对象的引用地址(注意,这是值传递)。故參数所指的对象和原始引用所指的对象都是堆中的同一个对象,故在測试方法中改动对象内容会改变对象的数据。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hkamo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

试试自己分析这个样例(跟上面是一样的):
package test;
public class A
{
int t = 6;
Object obj = new Object();
public static void main(String[] args)
{
A a = new A();
a.func(a.t,a.obj);//问t和obj的值是否变化。答案:不变化
}
public void func(int t,Object obj)
{
t = 7;
obj = null;
}
}
3.数组:
    3.1.对參数又一次赋值:
  public static void testArr(int[] arr)
{
arr = null;
}

測试:

int[] arr = {1,2};
System.out.println(arr[0]);//1
testArr(arr);
System.out.println(arr[0]); //1
传递机制跟对象一样,也是传递的对象地址,故而也不改变原始值。
     3.2.改变參数内部数据:
 public static void testArr(int[] arr)
{
arr[0] = 100;
}

測试:

int[] arr = {1,2};
System.out.println(arr[0]);//1
testArr(arr);
System.out.println(arr[0]);//100
结果无须解释了吧。
4.基本数据类型的包装类型:
    事实上跟基本类型是一样的。

public static void testWrapper(Float f)
{
f = 100.0f;
}

測试:

Float f = 12.0f;
System.out.println(f);//12.0
testWrapper(f);
System.out.println(f);//12.0
5.【重点】字符串:
字符串作为參数的情形比較特殊。
    5.1.对參数又一次赋值:
public static void testStr1(String str)
{
str = "testOK";
}

測试:

 String str = "test";
System.out.println(str);//test
testStr1(str);
System.out.println(str);//test

依据前面的思路,字符串也是对象,參数拷贝的是对象的地址。在方法内部将參数指向还有一个堆对象并不影响原始对象引用的指向。



 5.2.对參数运行替换、连接等操作:
 public static void testStr2(String str)
{
str = str.concat("OK");
str = str.toUpperCase();
}

測试:

String str = "test";
System.out.println(str);//test
testStr2(str);
System.out.println(str);//test
也是对str的又一次赋值。不改变原始串.
    5.3.对參数运行+的操作
public static void testStr3(String str)
{
str += "OK";
}

測试:

String str = "test";
System.out.println(str);//test
testStr3(str);
System.out.println(str);//test

假设你以为第二次输出testOK。那就错啦,String类的’+‘是经过重载的。编译时会还原成StringBuilder的append操作,而且new了一个StringBuilder对象:

str += "OK";
str = new StringBuilder(str).append("OK").toString();//编译时会还原成这样
显然也是对副本又一次赋值。并不影响原始的对象。

使用javap -c反编译一下会非常直观:

6.StringBuffer或StringBuilder作为參数:
    6.1又一次赋值
public static void testStringBuilder(StringBuilder sb)
{
sb = new StringBuilder("testOK");
}

測试:

StringBuilder sb = new StringBuilder("test");
System.out.println(sb.toString());//test
testStringBuilder(sb);
System.out.println(sb.toString());//test

6.2在方法内部调用StringBuffer或StringBuilder的append方法:

public static void testStringBuilder(StringBuilder sb)
{
sb.append("OK");
}

測试:

StringBuilder sb = new StringBuilder("test");
System.out.println(sb.toString());//test
testStringBuilder(sb);
System.out.println(sb.toString());//testOK
7.交换问题
    经过上面的样例。相信对java參数传递机制比較清楚了,所以请不要再写这种代码了:
public static void swap(Integer a, Integer b)
{
Integer temp = a;
a = b;
b = temp;
}

这根本不能交换两个数.







总结:

1.假设參数是基本数据类型(包含相应的包装类型)。那么參数传递时仅仅是原始值的一份拷贝或者叫副本,对副本操作并不影响原始值;
2.假设參数是对象(引用类型),那么參数传递时传递的是对象的地址的一份拷贝,所以对对象内部属性的操作会改变原始对象对应值,可是对该參数进行又一次赋值并不会影响原始对象;
3.String类型作为參数进行传递时,传递的也是地址。可是String类比較特殊,对參数进行concat,replace,’+‘等操作时不影响原始的串。对參数又一次赋值当然也不影响原始字符串。

4.数组类型作为參数跟传递对象时一样的。





java參数传递机制浅析的更多相关文章

  1. Java參数传递方式

    原文:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html,我作了些改动并添加了一个实例,添加对照 本文通过内存模型的方式来讨论一下Java中的參数 ...

  2. c++參数传递

    定义: 形參:指出如今Sub 和Function过程形參表中的变量名.数组名,该过程在被调用前.没有为它们分配内存.其作用是说明自变量的类型和形态以及在过程中的作用.形參能够是除定长字符串变量之外的合 ...

  3. FPGA编程基础(一)--參数传递与寄存器使用

    一.參数映射 參数映射的功能就是实现參数化元件.所谓的"參数化元件"就是指元件的某些參数是可调的,通过调整这些參数从而可实现一类结构类似而功能不同的电路.在应用中.非常多电路都可採 ...

  4. activity之间參数传递&&获取activity返回值&&activity生命周期

    Activity之间參数传递 A activity想将參数传给B activity时能够利用Intent将消息带过去 Intent intent = new Intent(this,BActivity ...

  5. 再次学习javascript中的參数传递

     javascript中的全部函数的參数传递都是依照值传递的,做了以下測试:    function addTen(num){ num +=10; return num; } var count = ...

  6. java的值传递机制

    一.练习:编写Java程序,将二维数组中的行列互调显示出来. 代码1为自己编写: package com.xxgpra.CH6; public class Hangliehudiao_pra4 { p ...

  7. ionic新手教程第七课-简要说明几种界面之间的參数传递及优缺点

    截至2016年4月13日19点32分,我公布的ionic新手教程,已经公布6课了, 总訪问量将近6000,平均每节课能有1000的訪问量.当中訪客最多的是第三课有2700的訪客. watermark/ ...

  8. Fragment进阶(四)----->參数传递3种写法

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  9. 关于mybatis中,批量增删改查以及參数传递的问题

    1.參数传递的问题 大多数情况下,我们都是利用map作为參数,而且大部分情况下都是仅仅有一个參数. 可是,我们也能够利用@param注解,来传入多个參数,此时,mybatis会自己主动将參数封装成ma ...

随机推荐

  1. Java发邮件:Java Mail与Apache Mail

    作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.邮件简介 一封邮件由很多信息构成,主要的信息如下,其他的暂时不考虑,例如抄送等: 1.收件人:收件人的邮箱地址,例 ...

  2. yzoi1777倒水问题的详细解法

    Description - 问题描述 x.y.z三个容器,其最大容量分别是xMAX升.yMAX升.zMAX升,这里规定100>xMAX>yMAX>zMAX.一开始x是装满了水的,现在 ...

  3. seaJs初体验

    目录结构 模块定义define define(function(require,exports,module){ //exports可以把方法或属性暴露给外部 exports.name = 'hell ...

  4. Bootstrap_表单_按钮

    一.多标签支持 一般制作按钮除了使用<button>标签元素之外,还可以使用<input type="submit">和<a>标签等. 同样,在 ...

  5. MOS管(场效应管)导通条件

    场效应管的导通与截止由栅源电压来控制,对于增强型场效应管来说,N沟道的管子加正向电压即导通,P沟道的管子则加反向电压.一般2V-4V就可以了.    但是,场效应管分为增强型(常开型)和耗尽型(常闭型 ...

  6. JQuery树形目录制作

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DT ...

  7. xgboost中如何自定义metric(python中)

    正好在参加携程的比赛,用的xgboost的算法,但携程比赛的测评函数比较奇怪,不是传统的那些,而是取precision≥0.97的情况下,recall的最大值.那无疑这个测评函数是要自己写的(官方没给 ...

  8. Start Your Django Project in Nginx with uWsgi

    Step 0:Install A,B,C,blabla needed This can be seen in my another article in the blog.click here(una ...

  9. 转:LESS CSS 框架简介

    原文来自于:http://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/ 简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTM ...

  10. 【转】近百个Android优秀开源项目

    近百个Android优秀开源项目   Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧 ...