之前朋友面试遇到了一个挺有趣的问题,题目如下:
public static void main(String[] args) throws Exception{ int a = 1; int b = 2; swap(a, b); System.out.println("a is "+a+", b is "+b); }
编写swap方法使a、b两个值交换数据,即a=2,b=1
这在个人知识范围内,觉得不可能实现,找了一段写的比较好的解释,如下:
java的基本数据类型共有8种,即int,short,long,byte,float,double,boolean,char(注意,并没有String的基本类型 )。
这种类型的定义是通过诸如int a = 1;long b = 255L;的形式来定义的。
如int a = 1;这里的a是一个指向int类型的引用,指向1这个字面值。这些字面值的数据,
由于大小可知,生存期可知(这些字面值定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。比如:
我们同时定义:
int a=1;
int b=2;
编译器先处理int a = 1;
首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为1的地址,没找到,就开辟一个存放1这个字面值的地址,然后将a指向3的地址。
接着处理int b = 2;在创建完b这个引用变量后,由于在栈中已经有2这个字面值,便将b直接指向2的地址。这样,就出现了a与b同时均指向2的情况。
定义完a与b的值后,再令a = 4;
那么,b不会等于4,还是等于2。在编译器内部,遇到时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;
如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
那怎么解决这个呢?
贴代码:
public static void main(String[] args) throws Exception { Integer a = 1333; Integer b = 2333; swap(a, b); System.out.println("a is "+a+", b is "+b); } private static void swap(Integer x, Integer y) throws Exception { int z= x; Field field = Integer.class.getDeclaredField("value"); field.setAccessible(true); field.set(x, y); field.set(y, z); System.out.println("x is "+x+", y is "+y); }
将基本类型改为对象类型,这样是不是就好了呢?看上去应该没什么问题,输出结果也是正确的,可试试a=1,b=2呢!
结果成了2 2,是不是觉得很怪异,JD反编译后如下:
private static void swap(Integer x, Integer y) throws Exception { int z= x; Field field = Integer.class.getDeclaredField("value"); field.setAccessible(true); field.set(x, y); field.set(y, Integer.valueOf(z)); System.out.println("x is "+x+", y is "+y); }
查看Integer源码valueOf(i)方法,就会发现原因了!
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
Integer是有自己的缓冲池[-128-128],field.set(x, y);这行代码会把缓冲池里面的值给修改了,将IntegerCache.cache[129]=IntegerCache.cache[130]=2
所以导致a=b=2,怎么破呢?
无非就是将获取的z值不走IntegerCache,那就直接new吧!修改代码
field.set(y, z);改为field.set(y, new String(z));问题解决,可还是最好不要使用公用的IntegerCache,继续修改代码:
public static void main(String[] args) throws Exception { Integer a = new Integer(1); Integer b = new Integer(2); swap(a, b); System.out.println("a is "+a+", b is "+b); }
成功了。
总结一下:
一)int数据存储在常量池,地址在栈。
二)Integer 定义的两个变量(如:integer a = 1; integer b = 2),它们公用一个IntegerCache。
相关推荐
面向对象的方法将数据及对数据的操作方法放在一起,作为一个相互依存、不可分离的整体--对象。对同类型对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口,与外界...
(s1+1运算结果是int型,需要强制转换类型) short s1 = 1; s1 += 1;(可以正确编译) 26、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? Math.round(11.5)==12 Math.round(-11.5)==-11 round方法返回与...
(s1+1运算结果是int型,需要强制转换类型) short s1 = 1; s1 += 1;(可以正确编译) 29、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? Math.round(11.5)==12 Math.round(-11.5)==-11 round方法返回...
若要格式化当前Locale的数值,可使用其中一个方法: myString = NumberFormat.getInstance().format(myNumber); 若要格式化不同 Locale 的日期,可在调用getInstance方法时指定它。 NumberFormat nf = ...
内容及步骤: 1、 设计一个图的类,采用临接表法进行存储,该图每个结点的数据类型类模板的模板参数进行定义(注:需先设计一个结点类Node); 2、 为该类分别设计一个实现深度优先搜索和广度优先搜索的成员...
这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包,Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。 有关规范 你也许对下面的这些Internet规范感兴趣,这些规范将直接影响到...
13.以下哪个数据结构不是多型数据类型(D )【中山大学 1999 一、3(1分)】 A.栈 B.广义表 C.有向图 D.字符串 14.以下数据结构中,(A )是非线性数据结构【中山大学 1999 一、4】 A.树 B.字符串 C.队 ...
//定义两个值类型变量 if (int.TryParse(txt_Num.Text, out P_int_Num) //判断输入是否是数值 && int.TryParse(txt_Key.Text, out P_int_Key)) { txt_Encrypt.Text = (P_int_Num ^ P_int_Key).ToString(); //加密...
根据数据结构中各数据元素之间前后件关系的复杂程度,一般将数据结构分为两大类型:线性结构与非线性结构。 (1)如果一个非空的数据结构满足下列两个条件: ① 有且只有一个根结点; ② 每一个结点最多有一个前件,...
4.5 我有一个char*型指针碰巧指向一些int型变量,我想跳过它们。为什么((int*)p)++;这样的代码不行? 4.6 为什么不能对void*指针进行算术操作? 4.7 我有些解析外部结构的代码,但是它却崩溃了,显示出了...
1.10 同一个静态(static)函数或变量的所有声明都必须包含static存储类型吗? 6 1.11 extern在函数声明中是什么意思? 6 1.12 关键字auto到底有什么用途? 7 类型定义(typedef) 7 1.13 对于用户定义类型,...
1.10 同一个静态(static)函数或变量的所有声明都必须包含static存储类型吗? 1.11 extern在函数声明中是什么意思? 1.12 关键字auto到底有什么用途? 类型定义(typedef) 1.13 对于用户定义类型,typedef 和#define有...
一个指向char类型的const对象指针,p不是常量,我们可以修改p的值,使其指向不同的char,但是不能改变它指向非char对象,如: const char *p; char c1='a'; char c2='b'; p=&c1;//ok p=&c2;//ok *p=c1;//error (2)...
由于每一像素(矩阵中每一元素)取值仅有0、1两种可能,所以计算机中二值图像的数据类型通常为1个二进制位。二值图像通常用于文字、线条图的扫描识别(OCR)和掩膜图像的存储。 2) 灰度图像: 灰度图像矩阵元素的...
在下列选项中,全部都合法的浮点型数据的选项为( a,b,d ),全部都不合法的浮点型数据选项是( c )。 (a) -1e3 , 15. , 2e-4 (b) 12.34 , -1e+5 , 0.0 (c) 0.2e-2.5 , e-5 (d) 5.0e-4 , 0.1 , 8.e+2...