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. 01-使用eclipse新建一个标准的 java web项目

    1.使用eclipse创建个普通的Java SE项目  名称:CRM java web标准目录结构 crm WEB-INF classes lib web.xml 设置项目字节码输出目录

  2. Linux常用命令 笔记

     Linux常用命令  笔记 一.文件处理命令 1. ls命令:显示目录文件                          -a 显示所有文件,包括隐藏文件.(all)               ...

  3. 用自己的话简要阐述struts2的执行流程

    Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件.核心控制器FilterDispatcher是Struts ...

  4. Android CheckBox修改大小、边框颜色,以及自定义CheckBox;

    CheckBox修改大小: android:scaleX="0.8" android:scaleY="0.8" CheckBox修改边框颜色,注意不是背景色: ...

  5. Linux中VIM的使用

    转自:http://www.lupaworld.com/?uid-296380-action-viewspace-itemid-118973 vi/vim 基本使用方法本文介绍了vi (vim)的基本 ...

  6. leetcode每日刷题计划-简单篇day9

    Num 38 报数 Count and Say 题意读起来比较费劲..看懂了题还是不难的 注意最后的长度是sz的长度,开始写错写的len 在下次计算的时候len要更新下 说明 直接让char和int进 ...

  7. (7/24) 插件配置之html文件的打包发布

    从前面几节到现在,其实我们的项目结构是有问题的,因为我们直接把index.html文件放到了dist文件夹目录下.这肯定是不正确的,应该放到我们src目录下,然后打包到dist目录下,前面为了学习,才 ...

  8. 原生js开发vue的双向数据绑定

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 嵌入式文件IO实验

    实验步骤: 1.arm-linux-gcc 交叉编译环境的安装.参考网站:https://jingyan.baidu.com/article/9c69d48f80282013c9024e20.html ...

  10. NodeJs 使用 multer 实现文件上传

    Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件 注意: Multer 不会处理任何非 multipart/form- ...