首页 > 试题广场 >

以下Java程序的执行结果是什么?

[单选题]
以下Java程序运行的结果是:
public class Tester{
public static void main(String[] args){
   Integer var1=new Integer(1);
   Integer var2=var1;
   doSomething(var2);
   System.out.print(var1.intValue());
   System.out.print(var1==var2);
}
public static void doSomething(Integer integer){
    integer=new Integer(2);
    }
}
  • 1true
  • 2true
  • 1false
  • 2false
java中引用类型的实参向形参的传递,只是传递的引用,而不是传递的对象本身。
自己画的图,而且没有visio!直接画图画的!

编辑于 2016-08-17 12:02:59 回复(41)
看了大伙的解析,我觉得很乱,各种说法都有,我也说一下我的理解:
(1)此题与装箱和拆箱没有关系。没有装箱的地方,也没有拆箱的地方。
(2)引用传递的误解。
-----------------------------------------------------
我先解释一下(1)。
对于Integer,如果装箱,会调用valueOf方法,如果拆箱,则会调用intValue方法,通过javap反汇编此题的源码可以发现,并会调用装箱与拆箱方法。所以,不涉及装箱与拆箱。

--------------------------------------------
对于(2)。
可能有些同学觉得,只要是引用传递,对引用的修改直接影响着原对象,其实不然,只有对引用对象的内部做了修改,才会影响原对象,如果直接将引用修改了,则对原对象没有影响,唯一的影响就是:这个被修改的引用,现在不是原来对象的引用,而是新对象的引用。
引用传递指的是传递的时候,传递的是对象的引用。如果对引用的内部成员进行操作,则会直接影响到原对象,但是如果直接把此引用指向了其他对象,那对不起,这个引用从此以后,便与之前的对象没有任何关系,当前代表的仅仅是新指向的对象。看下例子吧。
class SimInt{
    int value;
    public SimInt(int value){
        this.value=value;
    }
}
public class Main{
    public static void change1(SimInt si){
        si=new SimInt(3);//重新指向了新的对象,原对象不受影响
    }
    public static void change2(SimInt si){
        si.value=3;//通过引用操作对象内部成员,原对象被改变
    }
    public static void main(String args[]) {
	SimInt si1=new SimInt(1);
        System.out.println(si1.value);//输出1
        change1(si1);
        System.out.println(si1.value);//输出1
      change2(si1);
       System.out.println(si1.value);//输出3
    }
}

编辑于 2015-10-06 13:38:59 回复(32)
发表于 2016-07-21 11:43:09 回复(20)
Java中处理8种基本的数据类型用的是值传递,其他所有类型都用的是引用传递,由于这8种基本数据类型的包装类型都是不可变类,因此增加了对“按引用传递”的理解难度。其实还是很好理解的,题目中doSomething方法中new了一个对象,这是误导大家选择答案C的原因。其实,按引用传递的实质是将地址值的副本作为实参代替方法中的形参,因此var2与var1里面存储的地址值仍然是一样的,方法中操作的只是var2的一个副本值,并不影响var2本身存储的地址值,所以答案选择A。
发表于 2016-05-23 16:54:07 回复(12)
主要分析下doSomething(),因为这里传递的是引用,而不是地址值,即新建了一个Integer integer,其指向var2所指向的那个栈中的1.至此,integer和var毫无关系,除了同时指向同一个栈中的值。然后integer = new Integer(2);便是在栈中新建了一个为2的值,然后integer重新指向了这个栈中的值。所以var1和var2都没有改变,都是指向栈中为1的那个值。
同时说明下: == 与equal
equal是值的比较
==是引用的比较
现在很明显了吧。
发表于 2015-09-07 09:28:11 回复(16)
基本类型作为形式参数传递不会改变实际参数,引用类型作为形式参数传递会改变实际参数,但是JDK1.5以后,对基本类型的包装类型(int-Integer,double-Double)提供了自动拆装箱的功能,把Integer类型作为参数传递,会自动拆箱为基本类型,不会改变实际参数的值
发表于 2015-08-10 10:18:36 回复(5)
首先,var1--------->1 然后var2跟var1相同,于是 var2-------->1 然后integer跟var2相同,于是 integer--------->1 这个时候integer重新指向新对象, integer--------->3 所以,此时var1和var2一目了然了。
发表于 2015-10-19 18:16:18 回复(4)
是引用传递 和拆箱无关
引用传递是将实参的内存地址传递给形参 也可以理解为形参相当于新建的引用 该引用和实参指向相同的内存地址 所以doSomething(Integer integer)新建了引用integer 当doSomething(var2);被调用时 integer和var2指向了相同的内存地址. 当integer=newInteger(2);被调用时integer指向了新的内存地址 但这并没有改变var2指向的内存地址的值

发表于 2015-11-17 09:51:21 回复(1)
integer传的时候会拆箱,变成值传递
发表于 2015-08-07 17:10:48 回复(1)
这里不涉及装箱,拆箱,知识点来自core java: java里面参数传递只有按值传递 java方法的参数有两种, 1基本类型参数,基本类型传递的是本身拷贝的值,对于自身状态无影响。 2,对象参数传递,方法参数会改变对象本身状态。但是integer是final不可变类(包括String也是),因此,方法参数不会改变对象参数状态。 core java9 中文版第189页以及122页有详细解释!建议看一下!
发表于 2018-09-15 16:42:16 回复(2)
本题考查局部函数的形参和引用变量在内存的表示问题:
var1引用变量:指向了堆空间的对象new Integer(),对象内容为1;
var2:是var1的引用,指向与var1相同;
sth()函数式局部函数,生命周期是调用过后就垃圾回收
形参integer引用变量:var2引用赋值给integer,即integer是var2的引用,当形参传递时,var1,var2,integer指向同一个对象new Integer(1),进入函数指向代码后,显然 integer指向了new Integer(2)对象。然后结束生命周期integer引用也回收。

编辑于 2017-02-27 16:01:56 回复(0)
是因为integer是不可变类,
发表于 2016-07-16 23:37:48 回复(1)
其实上题这段代码就等价于下面这段代码:
public class Tester{
public static void main(String[] args){
    Integer var1=new Integer(1);
      Integer var2=var1;
      Integer integer = var2;
      integer = new Integer(2);
      System.out.print(var1.intValue());
      System.out.print(var1==var2);
}

发表于 2020-02-18 19:17:48 回复(0)
A:java中对象都是传引用方式,只有基本类型才是传值方式
编辑于 2015-08-23 14:00:41 回复(1)

   Integer var1=newInteger(1);
   Integer var2=var1;
   doSomething(var2);
   System.out.print(var1.intValue());
   System.out.print(var1==var2);
}
public static void doSomething(Integer integer){
    integer=newInteger(2);
    }
我就简单说说我自己的理解吧,首先创建一个Integer类型的对象var1,并传递一个int型参数1,此时1保存在堆内存new Integer()这个内存空间中,假设地址为0x0011,然后执行新创建一个Integer对象var2,并将var1所指向的地址0x0011赋值给var2,然后执行doSomething函数,Integer虽然是引用数据类型,但它里面的int数据是用final修饰的,不可变,所以参数传递时是值传递,所以doSomething函数并未对var2产生影响,然后执行intValue方法,将var1转换成int型的数据,再执行"=="号比较,"=="比较的是地址,var1和var2指向同一地址,所以输出为true,equals方法底层是用"=="实现的,所以默认为地址比较,但其他类都会对equals方法重写,使其进行值比较


发表于 2018-12-03 12:46:37 回复(0)
此处是引用传递,但是Integer中的value被final修饰,值不会更改
发表于 2015-07-17 21:56:28 回复(0)
解释一下,没有那么复杂,变量可以看成数据的地址,开始var1把地址赋值给var2,那么var2==var1就是true,后来var2作为形参传入doSomething方法,var2又赋值给integer,后来integer又被赋值,所以var2地址没变,所以选a
发表于 2018-05-28 14:37:02 回复(1)
integer传的时候会拆箱,变成值传递
发表于 2015-08-15 20:41:16 回复(1)
doSomething()的参数integer,开始与var2一同指向1,然后在这个方法里,他指向了2。于是,1的值没有改变。var1和var2的指向也没有改变。

详细及变形题见《一道网易笔试题引发的思考》
http://blog.sina.cn/dpool/blog/s/blog_5e1e51bb0100frc6.html
发表于 2015-04-06 17:26:54 回复(1)
我是这么想的:
1,在main方法中,var1 和var2 两个变量都是在栈中创建的(每个方法调用都会有自己的方法栈),指向的对象new Integer(1) 在堆中创建,
2,  然后在main方法中调用dosomething()方法,传入参数为var2,那么dosomething()方法被调用,创建自己的方法栈,栈中会创建一个变量integer ,值为var2,也就是var2代表的地址被复制一份给了integer。interger开始指向堆中的new Integer(1) 对象。后来在堆中新建了一个对象new Integer(2) ,integer指向这个新对象。此时的var1 和var2 都指向new Integer(1)对象。
3,dosomething() 方法执行完毕,方法栈被销毁,integer变量销毁,它指向的new Integer(2) 对象因为没有引用,所以也被销毁,回到main()方法中,此时var1 和 var2 还是指向的new Integer(1) 对象
。所以答案是 1 true ,选A
发表于 2022-06-11 20:07:21 回复(0)