首页 > 试题广场 >

如下代码,执行test()函数后,屏幕打印结果为()

[单选题]
如下代码,执行test()函数后,屏幕打印结果为()
public class Test2
{
    public void add(Byte b)
    {
        b = b++;
    }
    public void test()
    {
        Byte a = 127;
        Byte b = 127;
        add(++a);
        System.out.print(a + " ");
        add(b);
        System.out.print(b + "");
    }
}


  • 127 127
  • 128 127
  • 129 128
  • 以上都不对
推荐
答案:D
public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包(AutoBoxing/UnBoxing) Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。 add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127
编辑于 2015-01-30 14:47:14 回复(44)
该题的详细分析可参见博客:http://www.cnblogs.com/nailperry/p/4780354.html
这里简单说明两点:
1.b = b++;这一操作并未改变b的值,原因详见http://blog.csdn.net/lm2302293/article/details/6713147;
2.++a先是触发拆箱操作Byte.byteValue,得到基本类型的值127,然后执行+1操作,使得值变为-128,最后触发装箱操作Byte.valueOf将value=-128的Byte对象赋值给a。
下面通过反编译得到字节码详细说明++a的执行过程:
// 源代码
public static void main(String[] args) {
    Byte a = 127;
    ++a;
}
// 字节码
public static void main(java.lang.String[]);
    Code:
       0: bipush        127 // 将一个byte型常量值推送至操作数栈栈顶
       2: invokestatic  #2  // 自动装箱:访问栈顶元素,作为函数实参传入静态方法Byte.valueOf(byte),	   
							// 返回value值为127的Byte对象的地址,并压栈
       5: astore_1          // 将栈顶数值赋值给局部变量表中下标为1的引用型局部变量a,栈顶数值出栈。此时a对应的byte值为127。
       6: aload_1           // 局部变量表中下标为1的引用型局部变量a进栈		
       7: invokevirtual #3  // 自动拆箱,访问栈顶元素a,调用实例方法a.byteValue获取a所指Byte
							// 对象的value值,并压栈
      10: iconst_1			// int型常量值1进栈
      11: iadd				// 依次弹出栈顶两int型数值1(0000 0001)、127(0111 1111)
							//(byte类型自动转型为int类型)相加,并将结果128(1000 0000)进栈
      12: i2b				// 栈顶int值128(1000 0000)出栈,强转成byte值-128(1000 0000),并且结果进栈
      13: invokestatic  #2  // 自动装箱:访问栈顶元素,作为函数实参传入静态方法Byte.valueOf(byte),
							// 返回value值为-128的Byte对象的地址,并压栈
      16: astore_1			// 将栈顶数值赋值给局部变量表中下标为1的引用型局部变量a,栈顶数值出栈。此时a对应的byte值为-128。
      17: return
}
编辑于 2015-09-03 16:39:06 回复(12)


包装类的值都是final 不可变的,对于++b 或者b++ ,只是新创建了一个对象,然后把引用传给了原对象句柄,在函数中操作,只是形参的临时句柄改变了指向,实参的句柄还是指向原来的对象。所以即使不是b = b++ 这种,b的值在add之后也是不会变的。
发表于 2017-07-03 12:50:50 回复(15)
正确答案选D
add()方法里面的修改值并不会起作用,而add(++a)会使a数值越界成-128,所以输出为-128 127
发表于 2015-01-12 16:04:09 回复(3)
这个题涉及包装类的拆装箱,但如果你没看出来这一点,这个题依然能做对。
因为b = b++;  这一步根本没有改变b的值,因此 add函数只是个空壳子。
最大的坑在于,a、b是Byte类型,范围是 -128~127,++a后越界返回-128
发表于 2016-08-26 10:07:05 回复(2)
基本类型的值是保存在栈内存里面的,每个方法都有自己的栈内存,所以add(++a)里面的操作对test()里面的a并没有什么影响,++a 会溢出,++a的结果本来是1000 0000 又因为最高为为符号位,1表示负数,java 用补码来表示负数,所以它的值应该要-1再取反,-1:0111 1111 再取反 1000 0000 所以表示的是-128;add(b) 操作对test()里面的b值没影响,所以b = 127。
发表于 2015-08-08 21:44:21 回复(3)
感觉和拆箱装箱没关系,b = b++根本就是没有意义的代码。要么写成b++,要么写成b = b+1。
专门跑了一遍:
      public static void main(String args[]){
          int b = 10;
          b = b++;
          System.out.print(b);
      }
结果:10
发表于 2018-04-01 19:55:28 回复(5)
Byte是byte的包装类,运算操作都是对Byte.value进行的
一个byte 8位,最高位符号位
add方法不改变值,但是++a会
127=01111111(2)
加一得到
10000000
这是一个补码,并且是负数,各位取反再加一得到10000000(2)=128
所以第一个sout就输出-128
发表于 2016-09-23 11:56:48 回复(0)
Integer Byte String等这样的类比较特殊,可以理解和基本类型一样是值传递。所以,选d
发表于 2015-03-24 11:13:05 回复(0)
b = b++   等价于  脱裤子放屁 —— 毫无意义!!!
发表于 2021-07-18 01:24:33 回复(0)
选D
正确答案是-128和127
解释一下,这个题,就是引用传递,不过是因为包装类和String一样,都是不可变类。也就是说作为参数传递时,一开始实参和形参就不指向同一个地址。
add(++a),这个时候,是++a,a变成了-128然后作为参数传递了。
而add(b),还是b = 127。
看了高票去解释了拆装箱。其实这个不管拆没拆,都是在add方法中进行的,而add方法的形参和我们的实参并没有指向同一个地址。
发表于 2018-07-10 15:51:41 回复(0)
D
Byte的范围是-128~127,因此add(++a)会导致上溢得到add(-128),最后打印a为-127;
add(b)中b=b++,首先b赋值给b,然后b++,最终结果b为-128.
发表于 2015-01-26 12:11:27 回复(0)
1.add(++a)后,得到的是128,但因为byte型 范围是 -128-127 ,超出了范围 ,把128转换成二进制,然后把第一位当为符号位,所以是-128
2add(b)=127
发表于 2017-09-17 16:12:21 回复(0)
D.Byte类型数据范围是127到-128,++a是先自增1再进行运算,虽然是引用类型作为参数进行运算,但是jdk5提供了自动拆装箱功能,所以运算时还是值运算,也就是说形式参数的改变并不会影响实际参数,所以a最后的值为-128,b也同理,最后的值为127
发表于 2015-08-10 23:55:49 回复(0)
++a,虽然是类类型,但是执行了数***算,就会拆包变成byte型,byte型范围是-128-127,越界,编译会出错
发表于 2015-08-06 16:26:59 回复(0)
答案:D
我们先要知道一点,那就是Byte类型内部创建了一个静态数组,用来分别存储-128到127的Byte对象。咱们可以来看看这段代码:
public class Demo{
    public static void main(String[] args)
    {
        Byte a = 127;
        Byte b=a;
        System.out.println("结果1:"+(a==b));
        ++a;
        System.out.println("结果2:"+(a==b));
    }
}
它的输出结果是:
结果1:true
结果2:false
可以看到,值为-128和127时,指向的对象地址已经是不一样的了,类似于String类型。
所以,这里add函数只是个摆设,不管传递的是值还是对象地址,都影响不到变量a。所以,我们这里根本不需要考虑装箱和拆箱的问题。
编辑于 2022-08-05 17:23:14 回复(0)
答案是 D, a = -128, b = 127;
add()实现++操作,惠子欧东拆包成byte值传递类型,所以add()没有作用,++a,a = 127 + 1;  会越界,a = -128;
@牛客解题官

发表于 2022-04-03 19:37:14 回复(0)
a = -128 , b = 127
发表于 2020-10-10 16:03:38 回复(0)
破题,平时谁这么写?都不想用牛客网了。
发表于 2020-07-16 09:26:24 回复(1)
包装类的值都是final 不可变的,对于++b 或者b++ ,只是新创建了一个对象,然后把引用传给了原对象句柄,在函数中操作,只是形参的临时句柄改变了指向,实参的句柄还是指向原来的对象。所以即使不是b = b++ 这种,b的值在add之后也是不会变的。 b=b++先b=b然后b再自增 ++b是先加再赋值
编辑于 2019-07-09 20:00:19 回复(1)
越界是最骚的
发表于 2018-10-17 16:50:26 回复(0)