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

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. 异常练习一 throw

    package 异常练习;class OutageroudleException extends RuntimeException{ OutageroudleException(){ } Outage ...

  2. underscorejs-countBy学习

    2.20 countBy 2.20.1 语法 _.countBy(list, iteratee, [context]) 2.20.2 说明 排序一个列表组成一个组,并且返回各组中的对象的数量的计数.类 ...

  3. Silverlight开发工具汇总

    随着Silverlight技术的逐步完善,Silverlight应用大批的涌现,近期的2010年冬季奥运会,Silverlight作为首选视频播放技术,为全球提供在线赛事实况. Silverlight ...

  4. AspNet WebApi : MessageHandler(消息处理器 )

    1. Http Message Handler WebApi中的MessageHandler类似MVC中的filter,可用于请求/响应到达真正目标前对请求或者响应进行修改,比如:用户身份验证,请求头 ...

  5. javascript 设为首页 | 加入收藏夹 JS代码

    我们介绍一个可兼容所有浏览器的加入收藏代码代码,大概原理是这样的我们根据获取用户navigator.userAgent.toLowerCase()信息来判断浏览器,根据浏览器是否支持加入收藏js命令, ...

  6. Day8 面向对象(补充)

    私有字段 class Foo: def __init__(self, name): self.__name = name def f1(self): print(self.__name) class ...

  7. nosql数据库选型

    http://blogread.cn/it/article/6654 今天在书店里翻完了一遍<七天七数据库>.这本书简单介绍了postgreSQL,riak,mongodb,HBase,r ...

  8. Bug in Code

    Coder-Strike 2014 - Finals (online edition, Div. 1) C:http://codeforces.com/problemset/problem/420/C ...

  9. Android Wear计时器开发

    记得在2013年12月的时候,有系列文章是介绍怎么开发一个智能手表的App,让用户可以在足球比赛中记录停表时间.随着Android Wear的问世,在可穿戴设备中开发一款这样的App确实是个很不错的想 ...

  10. latch介绍

    latch是一种锁,用来实现对Oracle所有共享数据结构的串行化访问.共享池就是这样一个例子, 这是系统全局区中一个庞大的共享数据结构,Oracle正是在这里存储已解析,已编译的SQL. 修改这个共 ...