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. React 环境增加Redux ,React-Redux

    引入 Redux 的目的, 状态管理! React-Redux 就是完成一些粘合剂的作用. 简而化之的理解就是将数据放在store 中维护, 操作逻辑放在reducer中去写. 更功利的表达就是:  ...

  2. Ext 行统计有意思的实现.(js对象的循环, ext列的设置)

    考勤界面, 列包含日期. 行的数据格式:  需要实现 编辑一列然后在最后产生的统计的效果. 行数据内容. Gird Load 的时候统计数据:  -- 根据对象. 可以Ext.Date.parse 成 ...

  3. YUV介绍

    YUV444与YUV422下采样. 一.YUV介绍 YUV有三个分量:Y(Luminance/Luma:亮度).U和V表示色差,体现的是图片的色彩信息.相对于RGB彩色空间,将亮度信息和色彩信息分离. ...

  4. C语言博客作业5--指针

    C语言博客作业5--指针 1.本章学习总结(2分) 1.1思维导图 请以思维导图总结本周的学习内容,如下图所示: 1.2本章学习体会及代码量学习体会 1.2.1学习体会 描述本周学习感受,也可以在这里 ...

  5. DLC 基本定律与规则

    字母数字码 :除了数字以外,数字系统还需要处理数字以外的符号,如标点符号,控制命令等 最常见的是ASCII ASCII码是7位二进制码有128种组合,表示128个符号例如 二进制表示 十六进制表示 十 ...

  6. springboot+VUE(二)

    入element-ui cnpm install element-ui -S 执行后,会下载element-ui的包到本地,同时会将配置加入到package.json的依赖块中. 通过命令行可以将最新 ...

  7. python学习笔记---文件的操作

    数据的保存: 1.内存:常用的变量2.文件:文本内容,二进制的文件内容3.数据库: 读文件:1.要读取的文件路径一定要存在.2.打开存在的文件:open函数    参数1:文件的路径,相对的或者是绝对 ...

  8. jvm(一)类加载器

    1.jvm的生命周期结束的几种情况 a.执行了System.exit()方法 b.程序正常执行结束 c.程序在执行过程中遇到了异常或错误而异常终止 d.操作系统出现错误 2.类加载过程 加载:查找并加 ...

  9. 进制与进制转换DAY2

    进制和进制转换 一.进制的基础 1.十进制(案例) 系数:0-9 进位规则:逢十进一 权:基数的次幂 基数:几进制基数就是几 规律:右侧第一位的权是10的0次幂,每向左移动一位次幂会+1. 进制的表示 ...

  10. Image Storage