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

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

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

试试自己分析这个样例(跟上面是一样的):
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);//testtestStr1(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.数组类型作为參数跟传递对象时一样的。

转载于:https://www.cnblogs.com/mengfanrong/p/5262514.html

java參数传递机制浅析相关推荐

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

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

  2. C语言中函数和指针的參数传递

    C语言中函数和指针的參数传递 近期写二叉树的数据结构实验.想用一个没有返回值的函数来创建一个树,发现这个树就是建立不起来,那么我就用这个样例讨论一下c语言中指针作为形參的函数中传递中隐藏的东西. 大家 ...

  3. C# 多线程參数传递

    1.通过实体类来传递(能够传递多个參数与获取返回值),demo例如以下: 须要在线程中调用的函数: namespace ThreadParameterDemo {public class Functi ...

  4. java中值传递机制

    /** 方法的形参的传递机制:值传递* * 1.形参:方法定义时,声明的小括号内的参数* 实参:方法调用时,实际传递给形参的数据* * 2.值传递机制* 如果参数是基本数据类型,此时实参赋给形参的是实 ...

  5. java形参的传递机制

    package com.atguigu.java1; /** 方法的形参的传递机制:值传递* * 1.形参:方法定义时,声明的小括号内的参数* 实参:方法调用时,实际传递给形参的数据* * 2.值传递 ...

  6. Python学习笔记7:函数对象及函数对象作參数

    一.lambda函数 比如: fun1 = lambda x,y: x + y print fun1(3,4) 输出:7 lambda生成一个函数对象.该函数參数为x,y,返回值为x+y.函数对象赋给 ...

  7. 【Android 应用开发】Activity 状态保存 OnSaveInstanceState參数解析

    作者 : 韩曙亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38297083 一. 相关方法简单介绍 1. 状态保存方法演示 ...

  8. c语言指针和函数对数组A升序排序,函数指针作为函数參数,实现冒泡排序的升序排序和降序排序...

    #include #define N 10//定义数组元素个数 int Ascending(int a,int b);//升序排列的函数声明 int Descending(int a,int b);/ ...

  9. java之 ------ 可变參数和卫条件

    可变參数:适用于參数个数不确定.类型确定的情况,java把可变參数当做数组处理. 可变參数必须位于最后一项.当可变參数个数多于一个时,必将有一个不是最后一项,所以仅仅支持有一个可变參数. 可变參数的书 ...

最新文章

  1. Python模块及其导入
  2. 深度学习(七十四)半监督Mean teachers
  3. springwebflux 页面_Spring Security: Webflux 默认配置
  4. 【Linux】解决用vi修改文件,保存文件时,提示“readonly option is set”
  5. 并行程序设计---cuda memory
  6. java文件编译为class文件需要键入什么命令_Day02:Java语言基础-第一个Java程序以及编译与运行机制...
  7. CCD与CMOS的区别
  8. matlab函数建模例题,数学建模matlab上机实训题目答案
  9. Windows下Java环境配置
  10. OEM造就整个IT产业
  11. 卡西欧函数计算机广告词,卡西欧函数计算器,终身学习如有神助!
  12. android图片和文字设计,如何为图片加上精美文字?
  13. xbox one s驱动_【硬件资讯】次世代主机间最大差距?PS5 120Hz支持成难题,XBOX优势巨大!!...
  14. WPF界面-手机QQ_DEMO
  15. 论文阅读笔记:A Two-Step Approach for Event Factuality Identification
  16. JS简单实现鼠标跟随
  17. stm32串口通信最后一字节不对异常
  18. aspose-words 解决Linux word转pdf 乱码和出现小方块问题
  19. 1046 划拳 PTA
  20. 2013 province java c-2 组素数

热门文章

  1. VC2010如何给ActiveX添加事件
  2. 我的C语言可变参数的实现
  3. TCP/IP详解卷1中文版勘误表前言
  4. Taro+react开发(96):问答模块03
  5. JS中的异步任务有哪些
  6. 前端学习(2917):上午回顾
  7. [js] alert如何让文本换行?
  8. 前端学习(2852):简单秒杀系统学习之鼠标点击方法
  9. 工作107:vue调用视频接口
  10. 前端学习(2432):关于组件和目录名