关于Java通过反射实现交换两个数的值的解决与存在的一些问题
关于Java通过反射实现交换两个数的值的解决与存在的一些问题
关于Java通过反射实现交换两个数的值的解决与存在的一些问题
标签(空格分隔): 未分类
从网上找了很长时间相关的文章,绝大多数都是在参数另外加上一个数组,从
而实现,但我总感觉有点离谱-_-...,我有那时间,直接引入一个中间变量不就完
事了嘛。
哦对,还有创建了一个Swap类。。。。这这这-_-倒是也行,不过对于只是做
算法题来讲真的是有些麻烦了呢。
还有部分大佬用反射实现倒是实现了,不过有个细节不知道是不是没注意到,
接下来我就详细的说一下吧!
"啊咦哟哟"的解决(就是创建类和另加数组)
直接上代码
private static void swap(Integer a,Integer b){
try {
int temp = a;
Field field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
field.setInt(a, b);
field.setInt(b, temp);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
原理就是在Integer类中有一个value值,该变量存储了当前Integer对象的值,所以我们的目标就直接转移到:修改两个对象的value值
那么我们就可以通过反射来获取目标对象的value值,从而直接将两个目标对象修改(交换值)
这里要强调一点是:当将temp设置成Integer类型的时候,那么当a的值被修改后,temp的值会随之而改变,原因应该是由于:Integer中存在一个-127~128之间数的缓存,当缓存中存在某个值时,那么多个值相同的Integer对象的value都会指向这个缓存值,所以当a变了指向,那么temp = a即temp的指向也会随之改变
但是修改为int后则没有出现,原因我暂时不是很清楚,有几个猜测:
可能是因为创建为int后,temp的值指向不与Integer类的a同步,只是将a的value copy给了temp
int类内部无数值缓存机制
我们可以看到,虽然两个位置交换成功,但浏览整个数组,发现另外一个value为0的位置也被影响。
在之前,数组和缓存中的关系应该是这样的(如图):
当位置0和位置3发生指向交换时,代码明确告知了指向的方向,于是nums[0]->3,nums[1]->0,但是作为之前与位置0指向相同的位置2在没有被告知的情况下,于是其指向随着位置0一同修改了指向,所以值同时被更改
所以这种交换方法,在数组中不存在重复值时,可以使用。
但当存在相同值时,会对于交换对象值相同的元素也造成影响所以不应该在数组中使用
对于这个问题,我不知道有没有方法解决,期待各位大佬们的答案。
关于Java通过反射实现交换两个数的值的解决与存在的一些问题相关教程
Java继承------创建子类时自动与主动调用父类构造器
Java继承------创建子类时自动与主动调用父类构造器 static class SuperClass { SuperClass(){ System.out.println(父类无参构造方法); } SuperClass(int n) { System.out.println(父类有参构造方法); } } // SubClass 类继承 static class SubClass extends
1006 换个格式输出整数 (15分)【java题解】
1006 换个格式输出整数 (15分)【java题解】 题解: import java.util.*;public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); for (int i=0;i(n/100);i++) System.out.print(B); for (int
Intellij idea Language level和Java Compiler版本编译失败问题
Intellij idea Language level和Java Compiler版本编译失败问题 相信大家都遇到过用idea新建一个maven工程,编译时因为 Java 版本为1.5 而失败当原因。今天这篇博客就来分析下解决方法。 一般在开始编译工程时会先设置 Java 语言版本,即如下两个设置: 我们
Java中的微信支付(3):API V3对微信服务器响应进行签名验证
Java中的微信支付(3):API V3对微信服务器响应进行签名验证 微信支付 V3 版本前两篇分别讲了如何对请求做签名和如何获取并刷新微信平台公钥,本篇将继续展开如何对微信支付响应结果的验签。 微信支付会在回调的 HTTP 头部中包括回调报文的签名。商户 必须
1007 素数对猜想 (20分)【Java题解】
1007 素数对猜想 (20分)【Java题解】 题解: 1.判断出素数,用数组存起来2.记录相差 2 的的素数对个数3.输出即可 import java.util.*;public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(),
趣图:老码农的劝告
趣图:老码农的劝告 老码农的劝告 ↓↓↓ 有热门推荐1.Java学习路线(基础,源码,项目,实战)2.2019年Java基础学习阶段最新学习视频(限时领取)3.2019年Java高级进阶学习视频(限时领取)4.最新学习资源,看者有份,快来领取吧!5.阿里资深技术专家教你如
java.sql.SQLException: Unable to load authentication plugin
java.sql.SQLException: Unable to load authentication plugin ‘caching_sha2_password‘ 今天在跑一个flink程序,往MySQL存数据的时候,报这个错。 5.x版本是:default_authentication_plugin=mysql_native_password 8.x版本是:default_authentication_pl
*Java部分基础知识点总结归纳*
*Java部分基础知识点总结归纳* Java部分基础知识点总结归纳 基本数据类型和流程控制 基本类型的数据转换遵循此原则:小转大,直接转;大转小,需强转。按照数据类型从小到达顺序分为如下:byte--short--char--int--long--float--double,布尔不参与运算,因为