`
簡單從泚銷夨
  • 浏览: 74379 次
  • 性别: 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。

分享到:
评论

相关推荐

    zint_条码,二维码生成代码, 里面包含动态和静态库,支持png格式

    而二维码则更进一步,能够存储大量数据,包括文字、网址、联系信息等,并且可以水平和垂直两个方向上存储信息,因此比传统的条形码具有更高的数据密度。 **Zint库介绍** Zint是一款开源的、强大的条码和二维码生成...

    C#面向对象笔记大全[借鉴].pdf

    本PDF文件主要介绍了C#语言的面向对象编程相关知识点,涵盖了交换两个数据的值、定义方法、静态与非静态成员的调用方式、Main方法的四种形式、可变参数、代码规范、数组的定义和操作等方面的内容。 一、交换两个...

    Android AIDL 实现应用间数据交换(包括Parcelable数据)

    这里定义了两个方法,一个用于发送数据,一个用于接收数据。 **处理Parcelable数据** 在Android中,Parcelable是数据序列化的一种高效方式,常用于IPC。为了使自定义对象支持Parcelable,需要实现`Parcelable`接口...

    数据结构知识点整理

    冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。 ##### ϖ6. 快速排序 快速排序是一种非常高效的排序算法,采用分治法的思想,通过一趟排序...

    Activity之间的数据传递

    Intent的数据传递主要通过两个方法实现:putExtra()和getExtra()。例如,要从一个Activity A传递字符串数据到另一个Activity B,可以在A中创建Intent,然后调用putExtra()方法添加数据: ```java Intent intent = ...

    java练习题27.txt

    在这段代码中,通过定义了一个静态方法shuffle()来随机交换数组元素的位置: ```java public static void shuffle(int[] a) { for (int i = 0; i ; i++) { int j = new Random().nextInt(a.length); int t = a[i]...

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

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

    Android JSON数据的封装及解析

    2. **解析方法**:对应地,创建一个方法接收JSON字符串,返回特定的Java对象。 例如,创建一个名为`JsonUtil`的工具类: ```java public class JsonUtil { public static String toJson(Object object) { Gson ...

    注册界面(Activity的应用和数据传递)

    1. **通过Intent.putExtra()**:将基本类型、字符串、Parcelable、Serializable等数据类型放入`Intent`的额外数据中,然后在接收端通过`getExtra()`系列方法获取。 ```java // 发送端 Intent intent = new ...

    山大数据结构实验1

    - **交换函数** (`Swap`):用于交换两个变量的值。 ### 4. 代码解析 #### 4.1 输入处理 ```cpp int shuzu[10]; int i; int num = 0; cout ; cin &gt;&gt; i; while (i != 0 && num ) { shuzu[num] = i; cin &gt;&gt; i; num...

    Openmv通过串口接收数据、发送数据与stm32通信.docx

    例如,如果我们有两个8位的字节和两个32位的整数作为数据,可以这样做: ```python def send_data_packet(x, y): temp = struct.pack(", TITLE1, TITLE2, int(x), int(y)) uart.write(temp) ``` 这里的`表示两个...

    最新C#复习资料---实验报告单全部问题解答

    以下是一个交换两个值类型变量的泛型方法示例: ```csharp static void Swap(ref T a, ref T b) { T temp = a; a = b; b = temp; } // 使用示例 Swap&lt;int&gt;(ref m, ref n); ``` 上述代码在调用时,T会被...

    java面试习题Crystaljava面试习题Crystaljava面试习题Crystal

    2. **类型转换与变量声明**:在Java中,两个字节类型(byte)相加会自动提升为整型(int),因此在赋值给另一个字节变量时会导致编译错误,需要显式转换。 3. **Web Service与数据传输**:Web Service通常使用XML(可...

    C#判断数据类型的简单示例代码

    这个方法返回一个`System.Type`对象,该对象包含了关于对象的数据类型的所有信息。在示例代码中: ```csharp int i = 5; Console.WriteLine("i is an int? {0}", i.GetType() == typeof(int)); ``` 这里,`i....

    C语言基本数据类型及运算题库

    C语言是一种静态类型的编程语言,支持多种基本数据类型,包括整型(int、short、long等)、浮点型(float、double)、字符型(char)等。这些数据类型支持各种算术运算、逻辑运算和位运算等。 #### 二、知识点详细解析 *...

    java数据结构和算法

    - **思想**: 重复地遍历待排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 - **时间复杂度**: O(n^2),其中n是...

    冒泡排序的运算方法 一个简单的类

    `swap`方法用于交换数组中的两个元素。 ```java public static void swap(int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } ``` 4. **主函数**: 在`main`方法中,首先创建了一个`...

Global site tag (gtag.js) - Google Analytics