一、概述

目前各类语言中向函数传递参数的类型分为三种:

  1. 按值传递
  2. 按引用传递
  3. 按指针传递

其中按值传递表示方法(函数)接收的是调用者提供的变量的拷贝,不改变参数的值;按引用传递表示方法(函数)接收的调用者提供的变量地址;按指针传递表示方法(函数)接收的是调用者提供的指针的拷贝,不改变指针的值和地址,但可以改变指针所指向的地址。

java中没有指针和引用传递,只有值传递,因此,在函数中改变局部变量的参数不会影响到全局变量的值。

二、Java函数中数据交换的实质

此时,虽然局部变量str1和str2与全局变量的str1和str2同名,但是,局部变量得到的仅仅是常量区值的地址的拷贝;如果交换局部变量的值,只是改变了局部变量的指向;不会影响大到全局变量。而方法区中的常量是final类型的,更是不会改变。

示例如下: String x = new String("x111");

 String y = new String("y111");

 swap(x,y);
System.out.println(x);
System.out.println(y); public static void swap(String a, String b) {
String temp = a;
a = b;
b = temp;
} int[] arr = new int[3];
change(arr);
System.out.println(arr.length);

public static void change(int[] arr) {
  arr = Arrays.copyOf(arr, arr.length * 2);
 }

输出的结果是:x111,y111,3

有人可能会说,String是一个final类型的类,太过特殊,那我们使用包装类试试。示例如下,得到的结果仍然是:3,4

 Integer inteA = new Integer("3");
Integer inteB = new Integer("4");
swapInte(inteA, inteB);
System.out.println(inteA);
System.out.println(inteB); public static void swapInte(Integer InteA, Integer InteB) {
Integer temp = 0;
temp = InteA.intValue();
InteB = InteA;
InteA = temp;
}

由此可见,不论java向方法中传递的是基本类型的数据还是引用类型的数据,其实质都是将该变量指向的地址拷贝一份传给了局部变量,本质上拷贝的该变量指向的一个值,随便局部变量如何玩耍,都不会波及全局变量。

三、C语言的指针传递和C#的引用传递

为了对比说明值传递与指针传递、引用传递的区别,下面结合C指针传递和C#的引用传递说明下;

指针传递和引用传递的本质是将全局变量自身的地址传给了局部变量,因此,局部量修改时,同时也修改了全局变量的地址。

C语言的指针交换示例:

#include <stdio.h>

void swop(char **str1, char **str2)
{
char *temp = NULL; temp = *str1;
*str1 = *str2;
*str2 = temp;
} int main()
{
char *str1 = "hello";
char *str2 = "world"; printf("str1 = %s, str2 = %s\n", str1, str2);
swop(&str1, &str2);
printf("str1 = %s, str2 = %s\n", str1, str2);
return ;
}

C#的引用传递

       static void Main(string[] args)
{
string x = "hello";
string y = "world";
Console.WriteLine("x={0},y={1}",x, y);
Swap(ref x, ref y);
Console.WriteLine("x={0},y={1}", x, y);
Console.ReadKey();
}
static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = x;
}
static void Swap(ref string x, ref string y)
{
string temp = x;
x = y;
y = x;
}

四、Java数据交换的三种方法

那么,我们如何做到修改函数局部变量的同时也修改全局变量呢?

方式1:使用数组,此时修改的是全局变量和局部变量共同指向的地址中的值,因此,二者的值都会改变。

        int[] arr = {3,4};
System.out.println(arr[0]);
System.out.println(arr[1]);
arr = swap(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
public static int[] swap(int[] arr){
int temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
return arr;
}

方式2:使用反射

Integer inteA = new Integer("3");
Integer inteB = new Integer("4");
try {
swap(inteA, inteB);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(inteA);
System.out.println(inteB); public static void swap(Integer a1, Integer b1) throws Exception { Field value = Integer.class.getDeclaredField("value"); value.setAccessible(true); int temp = a1.intValue(); value.set(a1, b1.intValue()); value.set(b1, temp);
}

方式3:使用类封装的属性进行交换,这个方式网上例子很多,在此不再举例说明了。

总结:Java中方法的参数传递都是值传递,方法内局部变量的改变不会影响到全局变量。但是对局部变量和全局变量共同指向的值进行了修改的话,全局变量和局部变量的值都会改变。 

Java交换数据为何不起作用原因分析的更多相关文章

  1. SAP R3和JAVA交换数据之JCO

    SAP Java Connector (JCo)     SAP的JAVA中间件,使用它可以使SAP的客户和合作伙伴使用JAVA语言轻松地建立可以和SAP系统通信的兼容的组件和应用程序下面是JCo一些 ...

  2. Java -Dfile.encoding=UTF-8 出现乱码问题原因分析

    这两天写了一个 Java 程序来玩,结果又遭遇了以前遇到过很多次的乱码问题,具体描述一下: 在 Mac 系统里面,常用的 Java 程序启动方式有如下几种: 1.通过 eclipse 执行 class ...

  3. java.lang.OutOfMemoryError GC overhead limit exceeded原因分析及解决方案

    最近一个上线运行良好的项目出现用户无法登录或者执行某个操作时,有卡顿现象.查看了日志,出现了大量的java.lang.OutOfMemoryError: GC overhead limit excee ...

  4. java线程数据交换Exchanger

    两个线程都等到交换函数才能完成交换数据操作,代码如下: package threadLock; import java.util.Random; import java.util.concurrent ...

  5. Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型

    http://blog.csdn.net/a352193394/article/details/39503857  Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...

  6. Java并发工具类(四):线程间交换数据的Exchanger

    简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...

  7. Java并发编程--6.Exchanger线程间交换数据

    在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中 在生产者-消费者情境模式中它包含了一个数缓冲区 ...

  8. Java中数据类型转换&基本类型变量和对象型变量

    1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型    byte,short,int,lo ...

  9. Mybatis成为Java互联网时代首选持久框架的原因

    持久层可以将业务数据存储到磁盘,具备长期存储能力,只要磁盘不损坏(大部分的重要数据都会有相关的备份机制),在断电或者其他情况下,重新开启系统仍然可以读取这些数据.一般执行持久任务的都是数据库系统.持久 ...

随机推荐

  1. Django:验证码相关问题

    http://blog.csdn.net/csapr1987/article/details/7728315 https://zhidao.baidu.com/question/13837387222 ...

  2. 学成在线(第17天)用户认证 Zuul

    用户认证 用户认证流程分析 用户认证流程如下: 业务流程说明如下: 1.客户端请求认证服务进行认证.2.认证服务认证通过向浏览器cookie写入token(身份令牌)认证服务请求用户中心查询用户信息. ...

  3. Day9 - F - Monkey and Banana HDU - 1069

    一组研究人员正在设计一项实验,以测试猴子的智商.他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子.如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉.   ...

  4. 分享一款免费的工控组态软件(PCHMI)

    PCHMI严格的讲它并不是一款组态软件,也不是一款SCADA软件,而是一个基于.NET构架的DLL文件,开发者可以使用微软的Visual Studio将PCHMI.DLL加载到工具箱里面进行二次开发. ...

  5. 第1节 IMPALA:10、基本查询语法;11、数据加载的4种方式

    9.3. 创建数据库表 创建student表 CREATE TABLE IF NOT EXISTS mydb1.student (name STRING, age INT, contact INT ) ...

  6. VUE - mapState 辅助函数(简化)

    1,第一种 <template>   <div id="app">     <p> {{count}} </p>     <p ...

  7. LInux的服务器编码格式的查看与更改

    1.locale 命令查看字符编码 然后修改/etc/sysconfig/i18n,如改成中文编码: LANG=en_US.UTF-8 改为 LANG="zh_CN.GBK" 然后 ...

  8. 海康威视Web3.0控件个人开发经验及问题总结

    最近在给公司平台写视频监控的页面需求,于是接触到了海康威视的视频控件,网上查阅一番资料后,发现有很多大佬们给出了简易的海康视频控件的上手方法,但是发现仍然有很多地方没有总结到,于是在这里对我个人对海康 ...

  9. 解题报告:luogu P3853 [TJOI2007]路标设置

    题目链接:P3853 [TJOI2007]路标设置 是个水二分,那你还\(WA\).很简单,就是练了练和早上那题相似的题. 二分答案即可,复杂度\(O(Nlogl)\),可以通过本题. 不过,需要注意 ...

  10. word中图片的导出

    楼上说到的方法都是可行的,其实还有个更方便快捷的保存方式,特别是看到一篇word文档里有很多好看的图片想以图片格式单独保存下来观赏,用作其它,如QQ表情等,此方法更见优势:打开文档——文件——另存为— ...