一、概述

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

  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. Linux centosVMware df命令、du命令、磁盘分区

    一.df命令 df(disk filesystem的简写)用于查看自己挂载磁盘的总容量.使用容量.剩余容量,可以不加任何参数,默认以KB为单位. [root@davery ~]# df文件系统 1K- ...

  2. 083、Java数组之方法返回数组

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  3. 嵊州普及Day4T1

    题意:从n个数中选出k个数,使他们任意两数之差都等于m. 思路:任意差值都等于m,不就等价于k个数模m余数相同吗? 然后桶排储蓄一下各数余数即可. 见代码: #include<iostream& ...

  4. 嵊州普及Day3T1

    题意:n座山,每天袭击k面,不能为同一座.问最少几天袭击所有山两面. 思路:不管如何,n,k<=10,做了就能过,考试时先想的暴力模拟,后来发现有规律,看看就好了. 见代码: #include& ...

  5. Sqlserver 基本面试题

    一 单词解释(2分/个) 34分 Data 数据 Database 数据库 RDBMS 关系数据库管理系统 GRANT 授权 REVOKE 取消权限 DENY 拒绝权限 DECLARE 定义变量 PR ...

  6. Python集合语法

    a = {1,2,3,4,5,6,7,8,"aa","2"}    b = {2,3,4,5,6,7,8,9,99,7,6,6} v = a.intersect ...

  7. C语言学习巩固(泛型选择)

    在程序设计中,没有特定类型,但是一旦指定一种类型,就可以转换成指定类型的代码, 例如C++有一个关键tmeplate关键字用于声明模板,而模板的最大应用便是创建泛型算法.可惜的是c没有这个关键字 但是 ...

  8. 蓝桥杯 2n皇后问题

    题意: 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同一 ...

  9. mysql性能优化及 Comparison method violates its general contract

    项目上嵌套结果集查询,查询的列表再根据每个id进行查询计算,嵌套的sql如下: SELECT SUM(IFNULL(t.out_rate,0)) totalOutRate, SUM(IF(IFNULL ...

  10. SqlServer查看锁表与解锁

    某些情况下,sqlserver的表会被锁住,比如某个会话窗口有数据一直没提交,窗口又没关闭,这时表就会被锁住 其他任何连接查询表数据时都不会返回 这时需要手工杀掉产生死锁的会话ID,才能恢复正常 查看 ...