tech-daily-questions icon indicating copy to clipboard operation
tech-daily-questions copied to clipboard

「小马哥每日一问」2019.08.12 期

Open mercyblitz opened this issue 5 years ago • 19 comments

问题描述

public class Hamlet {
    public static void main(String[] args) {
        Random rnd = new Random();
        boolean toBe = rnd.nextBoolean();
        Number result = (toBe || !toBe) ?
                new Integer(3) : new Float(1);
        System.out.println(result);
    }
}

以上程序输出内容是?

(a) 运行时异常 (b) 3 (c) 1.0 (d) 以上答案都不是

请小伙伴们在评论区直接作答,谢谢~

注:请关注小马哥微信公众号【次灵均阁】,后续将有解答视频推送: 次灵均阁

mercyblitz avatar Aug 12 '19 14:08 mercyblitz

(b)

wangwengeek avatar Aug 12 '19 14:08 wangwengeek

d 从小马哥出题的规律来看,肯定不是个正常的结果,越复杂的越有可能

gzdzss avatar Aug 12 '19 14:08 gzdzss

3.0

scyslz avatar Aug 12 '19 14:08 scyslz

3.0,判断语句始终为true啊。。。

chihiro2014 avatar Aug 12 '19 14:08 chihiro2014

3.0 涨姿势

chilexun avatar Aug 12 '19 15:08 chilexun

(b)

feichangxinfu avatar Aug 12 '19 15:08 feichangxinfu

首先,toBe or notToBe 的结果肯定是 true,所以结果肯定和 3 有关; 那么,凭什么是 Integer 或者 凭什么就是 Float 呢,水平有限,类型提升吧我猜,只能 javap 感受一下:

// new Integer(3) 21: new #5 // class java/lang/Integer 24: dup 25: iconst_3 26: invokespecial #6 // Method java/lang/Integer."":(I)V 29: invokevirtual #7 // Method java/lang/Integer.intValue:()I

// new Float(1) 36: new #8 // class java/lang/Float 39: dup 40: fconst_1 41: invokespecial #9 // Method java/lang/Float."":(F)V 44: invokevirtual #10 // Method java/lang/Float.floatValue:()F

// Float.valueOf(3) 47: invokestatic #11 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float; 50: astore_3

所以,result.getClass() 的 结果是 java.lang.Float,程序输出是 3.0。

justmehyp avatar Aug 12 '19 15:08 justmehyp

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html

jinminer avatar Aug 12 '19 15:08 jinminer

@mercyblitz 稍做修改,还是那4个选项。:) Random rnd = new Random(); boolean toBe = rnd.nextBoolean(); Number a = new Integer(3); Number result = (toBe || !toBe) ? a : new Float(1); System.out.println(result);

dz005 avatar Aug 12 '19 16:08 dz005

改成 new Float(3) : new Integer(1),其他不变,字节码几乎一样

// new Float(3) 21: new #5 // class java/lang/Float 24: dup 25: ldc #6 // float 3.0f 27: invokespecial #7 // Method java/lang/Float."":(F)V 30: invokevirtual #8 // Method java/lang/Float.floatValue:()F

// new Integer(1) 36: new #9 // class java/lang/Integer 39: dup 40: iconst_1 41: invokespecial #10 // Method java/lang/Integer."":(I)V 44: invokevirtual #11 // Method java/lang/Integer.intValue:()I

// Float#valueOf 47: i2f 48: invokestatic #12 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;

justmehyp avatar Aug 13 '19 00:08 justmehyp

class文件反编译后变成以下: public static void main(String[] args) { Random rnd = new Random(); boolean toBe = rnd.nextBoolean(); Number result = !toBe && toBe ? new Float(1.0F) : (float)new Integer(3); System.out.println(result); }

也就是说在执行的时候Integer强制转成了float,不清楚为什么会这样

xtyfzhang avatar Aug 13 '19 01:08 xtyfzhang

d 三目运算符精度

wtthard avatar Aug 13 '19 01:08 wtthard

@mercyblitz 我还想问一个问题, 为什么以下代码,在jdk1.8 及以上版本没问题,jdk1.7及以下版本编译报错?

Random rnd = new Random();
boolean toBe = rnd.nextBoolean();
List<String> result = (toBe || !toBe) ?
  new ArrayList<String>() : 
  Collections.emptyList();

justmehyp avatar Aug 13 '19 02:08 justmehyp

Why is the class called Hamlet?

Fadezed avatar Aug 13 '19 02:08 Fadezed

Why is the class called Hamlet?

Because it's the magic :D

mercyblitz avatar Aug 13 '19 02:08 mercyblitz

d 三目运算符精度

正解

DuskDrum avatar Aug 13 '19 06:08 DuskDrum

涨知识了

programmerCs avatar Aug 13 '19 07:08 programmerCs

自动类型转化啊 Number result = (toBe || !toBe) ? a : new Float(1); Integer跟Float在一起 result 类型往上自动提升 ,int 自动转化 long float double 反之强转丢失精度

mingduo avatar Aug 13 '19 09:08 mingduo

三元运算符设计到一种双目运算符提升的特性 1.如果定义了数据类型的变量和未定义数据类型的变量参与双目运算符的后双目运算,那么返回的结果就是范围大(精度高)的类型。 2.如果两个定义了数据类型的变量参与双目运算符的后双目运算,那么返回的结果就是范围大(精度高)的类型。 3.如果直接进行数值的比较,则自动转型为范围大(精度高)的类型。

zhaozhiwei1992 avatar Aug 14 '19 01:08 zhaozhiwei1992