`
簡單從泚銷夨
  • 浏览: 73018 次
  • 性别: Icon_minigender_1
  • 来自: 文一西路969号
社区版块
存档分类
最新评论

交换两个int型数据的静态方法

    博客分类:
  • java
阅读更多

   

之前朋友面试遇到了一个挺有趣的问题,题目如下:

 

    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。

分享到:
评论

相关推荐

    语言程序设计课后习题答案

    面向对象的方法将数据及对数据的操作方法放在一起,作为一个相互依存、不可分离的整体--对象。对同类型对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口,与外界...

    java 面试题 总结

    (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方法返回与...

    超级有影响力霸气的Java面试题大全文档

    (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方法返回...

    java常用工具类的使用

    若要格式化当前Locale的数值,可使用其中一个方法: myString = NumberFormat.getInstance().format(myNumber); 若要格式化不同 Locale 的日期,可在调用getInstance方法时指定它。 NumberFormat nf = ...

    数据结构(C++)有关练习题

    内容及步骤: 1、 设计一个图的类,采用临接表法进行存储,该图每个结点的数据类型类模板的模板参数进行定义(注:需先设计一个结点类Node); 2、 为该类分别设计一个实现深度优先搜索和广度优先搜索的成员...

    java-servlet-api.doc

    这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包,Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。 有关规范 你也许对下面的这些Internet规范感兴趣,这些规范将直接影响到...

    《数据结构 1800题》

    13.以下哪个数据结构不是多型数据类型(D )【中山大学 1999 一、3(1分)】 A.栈 B.广义表 C.有向图 D.字符串 14.以下数据结构中,(A )是非线性数据结构【中山大学 1999 一、4】 A.树 B.字符串 C.队 ...

    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)如果一个非空的数据结构满足下列两个条件: ① 有且只有一个根结点; ② 每一个结点最多有一个前件,...

    你必须知道的495个C语言问题

    4.5 我有一个char*型指针碰巧指向一些int型变量,我想跳过它们。为什么((int*)p)++;这样的代码不行? 4.6 为什么不能对void*指针进行算术操作? 4.7 我有些解析外部结构的代码,但是它却崩溃了,显示出了...

    《你必须知道的495个C语言问题》

    1.10 同一个静态(static)函数或变量的所有声明都必须包含static存储类型吗? 6 1.11 extern在函数声明中是什么意思? 6 1.12 关键字auto到底有什么用途? 7 类型定义(typedef) 7 1.13 对于用户定义类型,...

    你必须知道的495个C语言问题.pdf

    1.10 同一个静态(static)函数或变量的所有声明都必须包含static存储类型吗? 1.11 extern在函数声明中是什么意思? 1.12 关键字auto到底有什么用途? 类型定义(typedef) 1.13 对于用户定义类型,typedef 和#define有...

    c++ 面试题 总结

    一个指向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)...

    imageprocess

    由于每一像素(矩阵中每一元素)取值仅有0、1两种可能,所以计算机中二值图像的数据类型通常为1个二进制位。二值图像通常用于文字、线条图的扫描识别(OCR)和掩膜图像的存储。 2) 灰度图像: 灰度图像矩阵元素的...

    C++复习资料之系列

    在下列选项中,全部都合法的浮点型数据的选项为( 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...

Global site tag (gtag.js) - Google Analytics