java中不同类函数间的参数java 传递函数指针问题?

函数调用参数传递类型(java)的用法介绍._百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
函数调用参数传递类型(java)的用法介绍.
&&函数调用参数传递类型(java)的用法介绍.
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢java&参数赋值和参数传递问题
在实际的开发过程中,方法调用是一种很常见的操作,在方法调用中,关于参数的处理可能很多进行实际开发的程序员都不一定理解的很清楚,下面系统的介绍一下Java语言中参数传递的规则,以及和参数传递相关的一些问题。
&&&&&&&&和其它程序设计语言类似,Java语言的参数传递也分为两种:
1、&按值传递(by
适用范围:8种基本数据类型、String对象
特点:在内存中复制一份数据,把复制后的数据传递到方法内部
作用:在方法内部改变参数的值,外部数据不会跟着发生改变
2、&按址传递(by
适用范围:数组、除String以外的其他所有类型的对象
特点:将对象的地址传递到方法内部
作用:在方法内部修改对象的内容,外部数据也会跟着发生改变
基础示例代码:
publicclass Test1{
publicstatic void t1(int n){
publicstatic void t2(String s){
&&&&&&&&&&&&&s
publicstatic void t3(int[] array){
&&&&&&&array[0]
publicstatic void main(String[] args){
&&&&&&&&&int
&&&&&&&t1(m);
&&&&&&&System.out.println(m);
&&&&&&&String
s1 = "abc";
&&&&&&&t2(s1);
&&&&&&&System.out.println(s1);
&&&&&&&&&int[]
arr = {1,2,3,4};
&&&&&&&t3(arr);
&&&&&&&System.out.println(arr[0]);
&&&&&&&&按照上面的参数传递规则,该代码的输出结果应该是:5&abc&2。因为int类型是按值传递,所以把参数m传递到方法t1时,相当于又复制了一份m的值,在方法t1内部修改的是复制后的值,所以m的值不变,s1的输出和m类似。而arr是数组,属于按址传递,也就是把arr的地址传递到了方法t3内部,在方法t3内部修改数组中的值时,原来的内容也发生改变。
&&&&&&&&以上特性是Java语言中的规定,在语法上无法指定参数传递是按值传递还是按址传递,但是可以通过下面的变换实现:
1、&对于按值传递的参数,如果需要在方法调用以后修改参数的值,可以利用返回值来实现。
2、&对于按值传递的参数,如果需要在方法内部修改时原来的参数不改变,则可以在方法内部重新创建该对象实现。
示例代码如下:
class Test2{
publicstatic int t1(int n){
&&&&&&&return
publicstatic String t2(String s){
&&&&&&&&&&&&&&&&s
&&&&&&&&&&&&&&&&&return&
publicstatic void t3(int[] array){
&&&&&&&//创建新的数组并赋值
&&&&&&&int[]
newArray = new int[array.length];
&&&&&&&//数据拷贝
&&&&&&&System.arraycopy(array,0,newArray,0,array.length);
&&&&&&&newArray[0]
publicstatic void main(String[] args){
&&&&&&&&&&&&&&&&int
&&&&&&&//重新赋值
&&&&&&&System.out.println(m);
&&&&&&&String
s1 = "abc";
&&&&&&&//重新赋值
&&&&&&&System.out.println(s1);
&&&&&&&&&&&&&&&&int[]
arr = {1,2,3,4};
&&&&&&&t3(arr);
&&&&&&&System.out.println(arr[0]);
这样,程序的输出结果就将是:10&123&&1。
在实际的程序开发中,可以根据需要使用类似的结构来进行实现。
&&&&&&&&下面再介绍一个参数传递的常见应用,利用参数传递实现返回值,这样的功能在IO类设计的read方法中大量使用。示例代码如下:
class Test3{
publicstatic void initArray(int[] array){
&&&&&&&&&&&&&&&&for(int
i = 0;i & array.i++){
&&&&&&&&&&&&&&&&&&&&&&&&&&array[i]
publicstatic void main(String[] args){
&&&&&&&&&&&&&&&&int[]
a = new int[10];
&&&&&&&initArray(a);
&&&&&&&for(int
i = 0;i & a.i++){
&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(a[i]);
&&&&&&&&在该示例代码中,在initArray方法内部修改了数组的值以后,外部数组a的值也会发生改变,间接实现了返回值的效果。当然,在该示例代码中,因为只返回一个参数,所以作用体现的不明显,如果需要返回多个参数时,使用按址传递是一种不错的主意。
参数的赋值
java中的数据类型主要包括两大类:
一、基本数据类型:boolean , byte , char ,short , int ,long ,float
二、引用类型:包括java类库中的已定义类型,和程序开发中要用到的自定义java类型,此外数组也是一种特殊的对象类型
java中参数传递的方式:
与C\C++中存在的两种方式------值传递、引用传递不同的是,在java语言中,只存在值传递这一种方式。
然而针对java中存在的两类数据类型来说,对于基本数据类型来说,传递的是类型值;对于对象引用类型来说,传递的是对象
的引用值;
方法体内部的变量赋值行为:
测试用例:
public class
ParamPassTest {
public static
void main(String[] args) { //基本数据类型测试 int i=10; int
j=i; System.out.println("在测试之前两int变量的值 :i="+i+" j="+j); j++;
System.out.println("j执行++操作后int两变量值 :i="+i+" j="+j); i++;
System.out.println("i执行++操作后int两变量值 :i="+i+" j="+j); //对象类型测试
StringBuilder src1=new StringBuilder("Source Str "); StringBuilder
src2=src1; System.out.println("在测试之前两个String变量的值 :src1="+src1+"
src2="+src2); src1.append("src1_append");
System.out.println("src1执行repleace操作后两String变量值 :src1="+src1+"
src2="+src2); src2.append("src2_append");
System.out.println("src2执行repleace操作后两String变量值 :src1="+src1+"
src2="+src2); } }
//测试结果
基本数据类型 在测试之前两int变量的值 :i=10 j=10
j执行++操作后int两变量值 :i=10 j=11 i执行++操作后int两变量值 :i=11 j=11 引用数据类型
在测试之前两个String变量的值 :src1=Source Str src2=Source Str
src1执行repleace操作后两String变量值 :src1=Source Str src1_append
src2=Source Str src1_append src2执行repleace操作后两String变量值
:src1=Source Str src1_appendsrc2_append src2=Source Str
src1_appendsrc2_a ppend
结果分析:
对于基本数据类型变量相互传递后,只是传递值,之后各变量的操作互不影响。
对于引用类型变量的相互传递后,由于是传递的引用,之后共同指向相同的对象,各引用变量都是操作同一个对象
简略图如下:初始化和赋值后的状态
<img ALT="java赋值运算与参数传递 - 白开水 - 白开水" src="/blog7style/images/common/sg_trans.gif" real_src ="http://img769.ph.126.net/mMcmA0X4pzBt6fj4OFaABg==/2275484.bmp" STYLE="line-height: 24.79 max-width: 100%; margin: 0px 10px 0px 0"
TITLE="java&参数赋值和参数传递问题" />
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。随笔- 637&
&&&&&&&&&&&
函数调用参数传递类型(java)的用法介绍.&
java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。
(一)基本数据类型:传值,方法不会改变实参的值。
public class TestFun {
public static void testInt(int i){
public static void main(String[] args) {
TestFun.testInt(a);
System.out.println("a="+a);
程序执行结果:a=0&。&
(二)对象类型参数:传引用,方法体内改变形参引用,不会改变实参的
引用,但有可能改变实参对象的属性值。
举两个例子:
(1)方法体内改变形参引用,但不会改变实参引用,实参值不变。
1 public class TestFun2 {
public static void testStr(String str){
str="hello";//型参指向字符串 &hello&
public static void main(String[] args) {
String s="1"
TestFun2.testStr(s);
System.out.println("s="+s); //实参s引用没变,值也不变
执行结果打印:s=1&
(2)方法体内,通过引用改变了实际参数对象的内容,注意是&内容&,引用还是不变的。
1 import java.util.HashM
3 import java.util.M
5 public class TestFun3 {
public static void testMap(Map map){
map.put("key2","value2");//通过引用,改变了实参的内容
public static void main(String[] args) {
Map map = new HashMap();
map.put("key1", "value1");
new TestFun3().testMap(map);
System.out.println("map size:"+map.size()); //map内容变化了
执行结果,打印:map&size:2&。可见在方法testMap()内改变了实参的内容。
(3)第二个例子是拿map举例的,还有经常涉及的是StringBuffer&:
1 public class TestFun4 {
public static void testStringBuffer(StringBuffer sb){
sb.append("java");//改变了实参的内容
public static void main(String[] args) {
StringBuffer sb= new StringBuffer("my ");
new TestFun4().testStringBuffer(sb);
System.out.println("sb="+sb.toString());//内容变化了
执行结果,打印:sb=my&java&。
所以比较参数是String和StringBuffer&的两个例子就会理解什么是&改变实参对象内容&了。
第一:java方法基本数据类型是传值,对象类型传引用,这是千真万确的。
第二:当参数是对象时,无论方法体内进行了何种操作,都不会改变实参 对 对象的引用。
第三:当参数是对象时,只有在方法内部改变了对象的内容时,才会改变实参对象内容。
进一步的思考&可以看出Java中参数的传递是传递的值,不过这个值有两种,一种是我们看得到的值,也就是primitive类型,比如int,double,char类型的值。另一种就是我们看不到的值,也就是地址值,也可以说是引用值,就是你传递对象或数组类型的参数时传递的值。&其实我们也可以这么理解,当传参数的时候,会把参数的primitive值或者引用值copy给形式参数。因此,任你在方法里面怎么修改这些值都不会对原来的变量有影响。&但是对于引用值,如果你在方法里面利用这个引用值访问对象或者数组里面的数据或方法的时候,这和在方法外面直接做事一样的。因为他们持有的是同一个地址。&理解了这些,试想一下,如果在参数前加上final有什么好处吗?&如果是primitive的参数,有什么用?只能是说你在方法里面不能修改这个变量的值。其实你就算修改了,也只是对方法自己有影响,不会对调用者有影响。&如果是引用类型的参数呢?又有什么用?不可能说不让你修改对象的值,只能不让你修改这个形式参数变量的引用值。到底有什么好处呢?&从设计API的角度来说,如果你在primitive参数上加上final,就是告诉自己,这些值对于我的方法来说就是常量,是我需要参考的东西。他们的值在我的整个方法的所有的地方都是一样的。试想,如果不加final,有可能你在方法里面前后两次访问这个变量的值不同,因为你在这之间无意中修改了它。这样就达不到你的意图。&那么如果是引用类型的参数呢?这里面的意图,就是告诉你在方法里面访问(不论是读还是修改)的这个对象就是传进来的对象,而不是别的。同样保证你在方法里面不同地方的操作都是对这一个对象的操作。&再进一步的思考&有了前面的思考,我们就可以知道,在设计方法的时候,尽量在参数前面加上final,不管是primitive类型的还是在引用类型的前面。因为这样意图非常简单清楚,在方法里面也可以大胆的引用。回顾你需要修改它们的时候,是不是无意中把他们当成自己定义的临时变量了,这样很危险,容易出乱子。这样是为什么当你用sun的规范做check style的时候他让你改的原因。&还要再来一点思考&为什么当你调用回调函数的时候必须得加final呢?看了一篇文章说是多线程以及垃圾回收的原因迫使的,我得研究以后再来补充。&
阅读(...) 评论()参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。
在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 应用程序是按值传递对象引用的。
Java 应用程序中的变量可以为以下两种类型之一:引用类型或基本类型。当作为参数传递给一个方法时,处理这两种类型的方式是相同的。两种类型都是按值传递的;没有一种按引用传递。
按值传递和按引用传递。按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。
1、对象是按引用传递的2、Java 应用程序有且仅有的一种参数传递机制,即按值传递3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
首先考试大来看看第一点:对象是按引用传递的  确实,这一点我想大家没有任何疑问,例如:  class Test01  {  public static void main(String[] args)  {  StringBuffer s= new StringBuffer("good");  StringBuffer s2=s;  s2.append(" afternoon.");  System.out.println(s);  }  }  对象s和s2指向的是内存中的同一个地址因此指向的也是同一个对象。  如何解释&对象是按引用传递的&的呢?  这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的,有问题吗?  程序运行的输出是:  good afternoon.  这说明s2和s是同一个对象。  这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)  再看看下面的例子:  class Test02  {  public static void main(String[] args)  {  int i=5;  int i2=i;  i2=6;  System.out.println(i);  }  }  程序的结果是什么?5!!!  这说明什么,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为下一个问题:Java 应用程序有且仅有的一种参数传递机制,即按值传递  class Test03  {  public static void main(String[] args)  {  StringBuffer s= new StringBuffer("good");  StringBuffer s2=new StringBuffer("bad");  test(s,s2);  System.out.println(s);//9  System.out.println(s2);//10  }  static void test(StringBuffer s,StringBuffer s2) {  System.out.println(s);//1  System.out.println(s2);//2  s2=s;//3  s=new StringBuffer("new");//4  System.out.println(s);//5  System.out.println(s2);//6  s.append("hah");//7  s2.append("hah");//8  }  }  程序的输出是:  good  bad  new  good  goodhah  bad  考试大提示: 为什么输出是这样的?  这里需要强调的是&参数传递机制&,它是与赋值语句时的传递机制的不同。  我们看到1,2处的输出与我们的预计是完全匹配的  3将s2指向s,4将s指向一个新的对象  因此5的输出打印的是新创建的对象的内容,而6打印的原来的s的内容  7和8两个地方修改对象内容,但是9和10的输出为什么是那样的呢?  Java 应用程序有且仅有的一种参数传递机制,即按值传递。  至此,我想总结一下我对这个问题的最后的看法和我认为可以帮助大家理解的一种方法:  我们可以将java中的对象理解为c/c++中的指针  例如在c/c++中:  int *p;  print(p);//1  *p=5;  print(*p);//2  1打印的结果是什么,一个16进制的地址,2打印的结果是什么?5,也就是指针指向的内容。  即使在c/c++中,这个指针其实也是一个32位的整数,我们可以理解我一个long型的值。  而在java中一个对象s是什么,同样也是一个指针,也是一个int型的整数(对于JVM而言),我们在直接使用(即s2=s这样的情况,但是对于System.out.print(s)这种情况例外,因为它实际上被?晃猄ystem.out.print(s.toString()))对象时它是一个int的整数,这个可以同时解释赋值的传引用和传参数时的传值(在这两种情况下都是直接使用),而我们在s.XXX这样的情况下时s其实就是c/c++中的*s这样的使用了。这种在不同的使用情况下出现不同的结果是java为我们做的一种简化,但是对于c/c++程序员可能是一种误导。java中有很多中这种根据上下文进行自动识别和处理的情况,下面是一个有点极端的情况:  class t  {  public static String t="t";  public static void main(String[] args)  {  t t =new t();  t.t();  }  static void t() {  System.out.println(t);  }  }
1.对象就是传引用2.原始类型就是传值3.String类型因为没有提供自身修改的函数,每次操作都是新生成一个String对象,所以要特殊对待。可以认为是传值。
阅读(...) 评论()}

我要回帖

更多关于 java 传递函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信