import java.lang.reflect.Field;

public class MainClass {
public static void main(String[] args) {
Integer a = 128;
Integer b = -129;
swarp(a,b);
System.out.println(a);
System.out.println(b);
try {
System.out.println("________________________________________________");
swarp1(a,b);
System.out.println(a);
System.out.println(b);
System.out.println("--------------------------------------------------");
Integer c = 128;
System.out.println(c);
Integer d = new Integer(128);
System.out.println("--------------------------------------------------");
swarp2(a,d);
System.out.println(a);
System.out.println(d); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
public static void swarp(Integer a, Integer b){
Integer temp = a;
a = b;
b = temp;
} public static void swarp1(Integer a, Integer b) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Field field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
Integer a1 = a;
field.set(a, b);
field.set(b, a1);
field.setAccessible(false);
}
public static void swarp2(Integer a, Integer b) {
Field field;
try {
field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
int a1 = new Integer(a);
field.set(a, b);
field.set(b, a1);
field.setAccessible(false);
} catch (NoSuchFieldException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

java 8
Integer 内部类

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}

内部类预初始化从-128~127的Integer实例,每个具体实例的下标为i + (-IntegerCache.low),比如-128下标为-128-(-128)=0,再看一下自动装箱的函数valueOf

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

到这里我们上面的类的结果已经很明显
一、将在main函数内,将a,b,c,d 分别赋值为128,-129,128,128
输出结果为:
128
-129
________________________________________________
-129
128
--------------------------------------------------
128
--------------------------------------------------
128
-129
二、将main函数内的a,b,c,d 分别赋值为127,-128,127,127
输出结果为:
127
-128
________________________________________________
-128
-128
--------------------------------------------------
-128
--------------------------------------------------
127
-128
如果读到这里还不知道为什么会有这样的结果,那么请继续看
1、java 的传参都是传值,函数接收到的形参都是指向实例引用的副本,第一个函数(swap)在内部的操作都是对副本的操作,所以不管值是多少,两个值得交换都失败
2、当ab的值在-128~127范围内时,第二个函数内,虽然给a做了备份,但是已经利用反射,将具体的在缓存内相应下标的Integer的value值改变,在b值赋值时,调用valueOf,指向该实例,所以返回的结果是ab值相等;而第三个函数为什么会交换成功呢?因为d是new出来的值,并没有走valueOf自动装箱,是一个在缓存之外的实例
3、当ab值在-128~127范围外时,ab都是new的新实例,固可以交换成功

Integer 函数传参实现值交换的更多相关文章

  1. [Java]_函数传参的疑惑与思考

    问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. void dfs(TreeNode node , int sum , ArrayList& ...

  2. 『Python × C++』函数传参机制学习以及对比

    一.Python函数传参 在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么 ...

  3. 函数传参传的是啥的思考【java Python】

    今天看<java 核心 卷1>的时候,作者提到了函数传参的问题,他提到,java传参,传的是值,而不是引用,然后,函数将要传的实参的值(如果实参是基本数据类型,那么就是值.如果实参是对象, ...

  4. C语言 指针在函数传参中的使用

    int add(int a, int b)   //函数传参的时候使用了int整型数据,本身是数值类型.实际调用该函数时,实参将自己拷贝一份,并将拷贝传递给形参进行运算.实参自己实际是不参与运算的.所 ...

  5. python函数传参是传值还是传引用?

    首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...

  6. pytest十一:函数传参和 firture 传参数 request

    为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行.但是登录 ...

  7. JS——变量和函数的预解析、匿名函数、函数传参、return

    JS解析过程分为两个阶段:编译阶段.执行阶段.在编译阶段会将函数function的声明和定义都提前,而将变量var的声明提前,并将var定义的变量赋值为undefined. 匿名函数: window. ...

  8. C#篇(三)——函数传参之引用类型和值类型

    首先应该认清楚在C#中只有两种类型: 1.引用类型(任何称为"类"的类型) 2.值类型(结构或枚举) 先来认识一下引用类型和值类型的区别: 函数传参之引用类型: 1.先来一个简单的 ...

  9. pytest_函数传参和firture传参数request

    前言为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...

随机推荐

  1. dll导出函数的两种方式的比较

    最初的网页链接已经挂了, 在此贴一个中间的转载链接 https://blog.csdn.net/zhazhiqiang/article/details/51577523 一 概要 vs中导出 dll的 ...

  2. [VS]VS2013中在一对大括号之间添加垂直虚线

  3. mysql-5.7.20

    . 下载mysql- wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.20-linux-glibc2.12-i686.tar. ...

  4. Win10和Ubuntu双系统搭建详

    最近学习云计算时,需要搭建xen和Hadoop,虚拟机容易出很多问题所以搭建了双系统,也方便以后的学习. 下面是详细搭建过程: 准备材料: U盘(容量>8G,最好是3.0接口速度快).Ultra ...

  5. [python,2019-02-15] 最短回文串

    给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa" 输出: "aaa ...

  6. 六、Python-字符串编码

      最早的编码为ASCII码(包含0-9.A-Z.a-z.符号(空格.制表符等)),最多支持256个符号(每个符号占1字节) GBK/GB2312:我国制定的中文编码标准,一个字节表示因为字母,两个字 ...

  7. LeetCode 86. Partition List 划分链表 C++

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

  8. SpringCloud系列十:SpringCloudConfig 高级配置(密钥加密处理(JCE)、KeyStore 加密处理、SpringCloudConfig 高可用机制、SpringCloudBus 服务总线)

    1.概念:SpringCloudConfig 高级配置 2.具体内容 在 SpringCloudConfig 之中考虑到所有配置文件都暴露在远程仓库之中的安全性问题,所以提供有安全访问的处理机制,这样 ...

  9. 10Linux_firewalld-Linux就该这么学

    firewalld: runtime:当前生效,重启后失效(默认) permanent:当前不生效,重启后永久生效. A:重启,B:执行firewall-cmd --reload 数据链路层:ipta ...

  10. Docker 容器操作命令

    容器是镜像的一个运行实例,镜像是静态的只读文件,而容器带有运行时需要的可写文件层.如果认为虚拟机是模拟运行的一整套操作系统(包括内核.应用运行态环境和其他系统环境)和跑在上面的应用,那么Docker容 ...