一、概述

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

  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. PEtools PE操作工具类C++

    源码来自各大网友并非原创修改了部分函数 仅供参考(PE没源码参考应该是很吃力的) 暂未更新完持续更新中....... PETools.h //函数头 int GetFileLength(FILE *p ...

  2. 哈希表,Java中的hashCode

    哈希表: 将我们所需的键通过哈希函数转换索引,然后存储在一个数组中. 哈希表是时间和空间之间的平衡,体现空间换时间的算法思想(联想到预加载,缓存等,有时候多存储,预处理缓存一些东西,带来时间复杂度的改 ...

  3. 十七 Spring的JDBC模版:使用开源连接池,DBCP,C3P0

    DBCP的配置以及使用 引入jar包

  4. 三、java基础-方法含义_重载_递归

    1.java中方法: 方法的含义: 就是一个代码片段,可以完后某个特定的功能,可以重复利用: 定义方法的语法: [方法的修饰符列表]   方法的返回值类型   方法名{    java语句; } 注意 ...

  5. 700k把web端程序包装为桌面程序

    electron因为自带cef所以体积巨大,还不是因为windows没有chromium的webview嘛,现在有了新edge后,这个项目通过依赖各个平台的webview,并依赖.net core,做 ...

  6. java小项目之:抽奖系统!java初学者必备(内附源码)

    [Java]Java摇奖源码,Java抽奖源码,Java随机抽奖源码 任务描述 本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了.注册 用 ...

  7. AC自动机 (模板)

    AC自动机是用来干什么的: AC自动机是用来解决多模匹配问题,例如有单词s1,s2,s3,s4,s5,s6,问:在文本串ss中有几个单词出现过,类似. AC自动机实现这个功能需要三个部分: 1.将所有 ...

  8. arm linux 移植 x265

    背景 本来想着把 x265编译到ffmpeg里面,搞定了x265的编译:但是一直报ERROR: x265 not found using pkg-config这个错误,我按照网上的资料,查看了ffbu ...

  9. Codeforces Round #624 (Div. 3)(题解)

    Codeforces Round #624 (Div.3) 题目地址:https://codeforces.ml/contest/1311 B题:WeirdSort 题意:给出含有n个元素的数组a,和 ...

  10. P1093 字符串A+B

    1093 字符串A+B (20分)   给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集.要求先输出 A,再输出 B,但重复的字符必须被剔除. 输入格式: 输入在两行中分别给出  ...