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

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. 使用Eclipse搭建C/C++开发环境(转)

    使用Eclipse搭建C/C++开发环境  文章出自:http://www.cnblogs.com/liuxianan/archive/2013/01/15/2861196.html 说明:网上有很多 ...

  2. 【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move

    Description 4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) ...

  3. js实现滑动解锁功能(PC+Moblie)

    http://dummyimage.com/600x400/ http://placehold.it/140x70 实现效果: css样式代码略. html代码: 页面上导入了jquery.mobil ...

  4. kafka监控

    做kafka相关项目,需要用到监控的东东,找到了两个方法 第一个: http://quantifind.com/KafkaOffsetMonitor/ 非常容易上手,效果也直观,可以显示各个topic ...

  5. pkg-config相关的常用指令

    pkg-config用途: 查询系统已安装库的基础信息(元信息) 1.查看所有的pkg-config库 pkg-config --list-all --list-all  列出pkg-config路径 ...

  6. APUE《UNIX 环境高级编程》读后感

    今天终于把APUE前17章全部看完了,基本上主要知识就在这些章节里. 之前看完<unix/linux编程实践教程>时,有一种豁然开朗.心旷神怡的感觉,在代码级别了解了linux很多系统机制 ...

  7. elasticsearch 性能优化

    #系统默认的最大打开文件数的限制 vi /etc/security/limits.conf   *     -       nproc          50240    *     -       ...

  8. Objective-c之NSCopying

    Objective-c之NSCopying     copy的原理: 执行<NSCopying>协议,类中必须实现copyWithZone:方法响应的copy消息. copy消息将发送co ...

  9. RocksDB介绍:一个比LevelDB更彪悍的引擎

    关于LevelDB的资料网上还是比较丰富的,如果你尚未听说过LevelDB,那请稍微预习一下,因为RocksDB实际上是在LevelDB之上做的改进.本文主要侧重在架构上对RocksDB对LevelD ...

  10. iOS Developer Libray (中文版)-- About Objective-C

    该篇是我自己学习iOS开发时阅读文档时随手记下的翻译,有些地方不是很准确,但是意思还是对的,毕竟我英语也不是很好,很多句子无法做到准确的字词翻译,大家可以当做参考,有错误欢迎指出,以后我会尽力翻译的更 ...