一个笔试题,补充完整下面的代码,要求是,交换两个数字。
    public static void swap(Integer x, Integer y) {
        
    }    public static void swap(int x, int y) {
        
    }我的解答---------------------------package com.yang.bean;import java.lang.reflect.Field;public class Number {                public static void swap(Integer a, Integer b) {               
                                                Class<?> aType = a.getClass(); 
                                Class<?> bType = b.getClass(); 
                                Integer c = b;                          
                                try {
                                        Field afield = aType.getDeclaredField("value");
                                        afield.setAccessible(true);  
                                        afield.set(a, b);  
                                        Field bfield = bType.getDeclaredField("value");
                                        bfield.setAccessible(true);  
                                        bfield.set(b, c);  
                                } catch (Exception e) {
                                        e.printStackTrace();
                                } 
                        }
  public static void main(String[] args) {
        Integer a = 3;
        Integer b =  5;
        System.out.println(a);
        System.out.println(b);
         Number.swap(a, b);
        System.out.println(a);
        System.out.println(b);
          
  }}这个方法我试了,输出结果是3 5 5 5
只能把第一个数变成第二个数,而第二个数没变,我考虑了,你要想得到第一个数,而这时第一个数已经被你用第二个数替换了,所以,第一个数就没了。就得到这种结果!你引用地址没变而地址里的内容变了。所以先找个新的吧它寄存起来,可以new一下最后还是没成功!求高手出招Java面试题

解决方案 »

  1.   

    虽然我不知道为什么,但是把field.set改成field.setInt就好了
      

  2.   

    1.你的算法错了:c中应该保存a的值。
    2.对象和对象的引用没分清楚。
      不要用 Integer c = a,那样a和c就指向同一个对象了。
      应该写成Integer c = new Integer(a),程序就没问题了。
    3.反射的概念不清楚。  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
      试试下面的代码。
      public static void swap(Integer a, Integer b) {               
              Class type = a.getClass(); 
              Integer c = new Integer(a);
              try { 
               Field value = type.getDeclaredField("value");
               value.setAccessible(true);  
               value.set(a, b);  
                  value.set(b, c);  
              } catch (Exception e) {
                      e.printStackTrace();
              } 
        }
      

  3.   

      一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
      试试下面的代码。
      public static void swap(Integer a, Integer b) {               
              Class type = a.getClass(); 
              Integer c = new Integer(a);
              try { 
               Field value = type.getDeclaredField("value");
               value.setAccessible(true);  
               value.set(a, b);  
                  value.set(b, c);  
              } catch (Exception e) {
                      e.printStackTrace();
              } 
        }
    我想通了。我之前的代码是这样:
    public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
        Field field = new Integer(5).getClass().getDeclaredField("value");
        field.setAccessible(true);
        int c = a;
        field.setInt(a, b);
        field.setAccessible(true);
        field.setInt(b, c);
      }当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象
      

  4.   

    只能说,这题是个啥表。如果你改了一个API约定的immutable对象,那就会造成严重后果。比如你把Integer(3)的value改成了5,那以后所有的3装箱之后都变成了5。至于第二个,传俩int进来,应该是无解的。
      

  5.   

    我来帮你解决,下面是一个demo:
    public void change(int a,int b)
    {
       int temp = a;
       a = b;
       b = temp;
      System.out.println("此时的a="+b+"此时的b="+a);
      希望能够帮组你
    }
      

  6.   

    最经典的答案:
    LZ可以把它背下来
    public static void swap(int x, int y) {
            x=x+y;
            y=x-y;
            x=x-y;
        }
      

  7.   


    public class SwapTest {
    static Integer a;
    static Integer b;
    int i, j; public SwapTest(int i, int j) {
    this.i = i;
    this.j = j;
    } public SwapTest() { } public void setX(Integer a) {
    this.a = a;
    } public void setY(Integer b) {
    this.b = b;
    } public void swap() {
    int temp;
    temp = i;
    i = j;
    j = temp;
    } public static void swap(Integer x, Integer y) {
    SwapTest swap = new SwapTest();
    swap.setX(y);
    swap.setY(x);
    } public static void main(String[] args) { SwapTest st = new SwapTest(1, 2);
    st.swap();
    System.out.print("x=" + st.i+" ");
    System.out.println("y=" + st.j);
    a = new Integer(1);
    b = new Integer(2);
    swap(a, b);
    System.out.print("a=" + a.intValue()+" ");
    System.out.println("b=" + b.intValue());
    }}
      

  8.   

    额……上面的有个swap方法忘了带参了,随便加两个参数就好了,不影响结果。public class SwapTest {
    static Integer a;
    static Integer b;
    int i, j; public SwapTest(int i, int j) {
    this.i = i;
    this.j = j;
    } public SwapTest() { } public void setX(Integer a) {
    this.a = a;
    } public void setY(Integer b) {
    this.b = b;
    } public void swap(int a,int b) {
    int temp;
    temp = i;
    i = j;
    j = temp;
    } public static void swap(Integer x, Integer y) {
    SwapTest swap = new SwapTest();
    swap.setX(y);
    swap.setY(x);
    } public static void main(String[] args) { SwapTest st = new SwapTest(1, 2);
    st.swap(0,0);
    System.out.print("x=" + st.i+" ");
    System.out.println("y=" + st.j);
    a = new Integer(1);
    b = new Integer(2);
    swap(a, b);
    System.out.print("a=" + a.intValue()+" ");
    System.out.println("b=" + b.intValue());
    }}
      

  9.   

    static又忘了加了,好吧,我脑子里都是浆糊。public class SwapTest {
    static Integer a;
    static Integer b;
    static int i, j; public SwapTest(int i, int j) {
    this.i = i;
    this.j = j;
    } public SwapTest() { } public void setX(Integer a) {
    this.a = a;
    } public void setY(Integer b) {
    this.b = b;
    } public static void swap(int a,int b) {
    int temp;
    temp = i;
    i = j;
    j = temp;
    } public static void swap(Integer x, Integer y) {
    SwapTest swap = new SwapTest();
    swap.setX(y);
    swap.setY(x);
    } public static void main(String[] args) { SwapTest st = new SwapTest(1, 2);
    st.swap(0,0);
    System.out.print("x=" + st.i+" ");
    System.out.println("y=" + st.j);
    a = new Integer(1);
    b = new Integer(2);
    swap(a, b);
    System.out.print("a=" + a.intValue()+" ");
    System.out.println("b=" + b.intValue());
    }}
      

  10.   

      一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
      试试下面的代码。
      public static void swap(Integer a, Integer b) {               
              Class type = a.getClass(); 
              Integer c = new Integer(a);
              try { 
               Field value = type.getDeclaredField("value");
               value.setAccessible(true);  
               value.set(a, b);  
                  value.set(b, c);  
              } catch (Exception e) {
                      e.printStackTrace();
              } 
        }
    我想通了。我之前的代码是这样:
    public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
        Field field = new Integer(5).getClass().getDeclaredField("value");
        field.setAccessible(true);
        int c = a;
        field.setInt(a, b);
        field.setAccessible(true);
        field.setInt(b, c);
      }当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象
    这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下
      

  11.   

      一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
      试试下面的代码。
      public static void swap(Integer a, Integer b) {               
              Class type = a.getClass(); 
              Integer c = new Integer(a);
              try { 
               Field value = type.getDeclaredField("value");
               value.setAccessible(true);  
               value.set(a, b);  
                  value.set(b, c);  
              } catch (Exception e) {
                      e.printStackTrace();
              } 
        }
    我想通了。我之前的代码是这样:
    public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
        Field field = new Integer(5).getClass().getDeclaredField("value");
        field.setAccessible(true);
        int c = a;
        field.setInt(a, b);
        field.setAccessible(true);
        field.setInt(b, c);
      }当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象
    这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下public class Test {  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Integer a = 5;    Field field = a.getClass().getDeclaredField("value");
        field.setAccessible(true);
        field.set(a, 4);    Integer b = 5;
        System.out.println(b);
      }
    }请问b输出啥?这是我之前讨论的东西
      

  12.   

            Integer a = 10;
            Integer b = 11;
            int temp = a.intValue(); 
            a = b.intValue();
            b = temp;
    难道我把问题想简单了?
      

  13.   

    Integer a = 1;
    Integer b = 3;

    Integer c = 0;
    c = a;
    a = b;
    b = c;

    System.out.println(a+":"+b);
      

  14.   

    public static void swap(Integer a,Integer b){
    try {
    Integer c = new Integer(a);
    Field field = a.getClass().getDeclaredField("value");
    field.setAccessible(true);
    field.set(a, b);

    Field field1 = b.getClass().getDeclaredField("value");
    field1.setAccessible(true);
    field1.set(b, c);

    } catch (Exception e) {
    e.printStackTrace();
    }
    }
      

  15.   


    这么多楼里唯一正解就是你了!
    new Integer 在小于128 的时候会重用已有的Integer对象,看SUN JDK的源码可知。
    通过反射强行改了值,以后的代码就惨了。所以这样的题目确是很无聊。第二题倒也不是完全没办法,
    可以在方法中呼叫Native方法,或者启动Agent去Hack正在运行JVM,
    然后就是C的工作了,找到操作数地址,改之。
    坑爹题。
      

  16.   

      一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
      试试下面的代码。
      public static void swap(Integer a, Integer b) {               
              Class type = a.getClass(); 
              Integer c = new Integer(a);
              try { 
               Field value = type.getDeclaredField("value");
               value.setAccessible(true);  
               value.set(a, b);  
                  value.set(b, c);  
              } catch (Exception e) {
                      e.printStackTrace();
              } 
        }
    我想通了。我之前的代码是这样:
    public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
        Field field = new Integer(5).getClass().getDeclaredField("value");
        field.setAccessible(true);
        int c = a;
        field.setInt(a, b);
        field.setAccessible(true);
        field.setInt(b, c);
      }当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象
    这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下public class Test {  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Integer a = 5;    Field field = a.getClass().getDeclaredField("value");
        field.setAccessible(true);
        field.set(a, 4);    Integer b = 5;
        System.out.println(b);
      }
    }请问b输出啥?这是我之前讨论的东西这有关系么?输出的4,B跟A指向的是同一块内存,-128到127自动拆装箱只会生成一个对象...你把B= 5换成其他的,你看还会一样么?归根结底就是内存分配的问题
      

  17.   

     Integer a = 10;
             Integer b = 11;
             int temp = a.intValue(); 
             a = b.intValue();
             b = temp;
    难道我把问题想简单了? 
    21楼正解!
      

  18.   

    这个问题很有意思,考的是对象的传递。
    public static void swap(Integer x, Integer y)
    方法的参数x,与main方法中所声明的变量x虽然都指向了相同的地址,但始终是两个变量。
    虽然很多人写了,Integer c = new Integer(x);或是 Integer c = x; 但c始终只是另外一个指向
    相同地址的变量,也就是说以下代码:
    public static void swap(Integer x, Integer y){
        Integer c = x;
        x = y;
        y = c;
    }
    只是swap方法内部的变量交互了地址,而不是main方法中的变量交互了地址,无论swap方法如何交换,其实都没main方法变量的事。还有 29楼的 wei323001 ,你好像还没搞清楚什么是重载。
    你的代码明显两次都是调用了public static void swap(int x, int y) 。当然这问题我也没解决,但看出来,出这考题的人应该是对Java很熟悉的人
      

  19.   

    public static void swap(int x,int y){
    }
    两个int类型的参数能实现交换吗,不是值传递不能改变原参数的吗,求高人指点