一个笔试题,补充完整下面的代码,要求是,交换两个数字。
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面试题
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();
}
}
试试下面的代码。
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对象
public void change(int a,int b)
{
int temp = a;
a = b;
b = temp;
System.out.println("此时的a="+b+"此时的b="+a);
希望能够帮组你
}
LZ可以把它背下来
public static void swap(int x, int y) {
x=x+y;
y=x-y;
x=x-y;
}
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());
}}
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());
}}
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());
}}
试试下面的代码。
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 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输出啥?这是我之前讨论的东西
Integer b = 11;
int temp = a.intValue();
a = b.intValue();
b = temp;
难道我把问题想简单了?
Integer b = 3;
Integer c = 0;
c = a;
a = b;
b = c;
System.out.println(a+":"+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();
}
}
这么多楼里唯一正解就是你了!
new Integer 在小于128 的时候会重用已有的Integer对象,看SUN JDK的源码可知。
通过反射强行改了值,以后的代码就惨了。所以这样的题目确是很无聊。第二题倒也不是完全没办法,
可以在方法中呼叫Native方法,或者启动Agent去Hack正在运行JVM,
然后就是C的工作了,找到操作数地址,改之。
坑爹题。
试试下面的代码。
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换成其他的,你看还会一样么?归根结底就是内存分配的问题
Integer b = 11;
int temp = a.intValue();
a = b.intValue();
b = temp;
难道我把问题想简单了?
21楼正解!
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很熟悉的人
}
两个int类型的参数能实现交换吗,不是值传递不能改变原参数的吗,求高人指点