Java : 踩过这个坑没? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
oska117
V2EX    程序员

Java : 踩过这个坑没?

  •  
  •   oska117 2019-06-12 20:41:30 +08:00 6976 次点击
    这是一个创建于 2319 天前的主题,其中的信息可能已经有所发展或是发生改变。
    String a = "a"; String b = "b"; String c = a + "_" + b==null?"":b; 

    上面的代码我一直以为 c 会返回 "a_b"

    实际上却返回的是 "b" (+运算符优先级高于三目)

    为啥我一直觉得 这样写没问题呢?

    关键是我同事也有这种错觉。

    68 条回复    2019-06-26 20:19:52 +08:00
    GPLer
        1
    GPLer  
       2019-06-12 20:46:12 +08:00 via Android   1
    没记错的话三目运算符的优先级是最低的,使用时本来就要注意加括号,之所以你认为没问题是因为错误的缩进。
    rainmakeroly
        2
    rainmakeroly  
       2019-06-12 20:50:14 +08:00 via Android   1
    不是错觉,是二。有括号不用。
    hoyixi
        3
    hoyixi  
       2019-06-12 20:55:25 +08:00   22
    这样写代码的早点开除,生活能更美好点
    wucao219101
        4
    wucao219101  
       2019-06-12 20:56:41 +08:00   2
    键盘上的括号是黄金按钮舍不得按吗?哈哈
    zhaishunqi
        5
    zhaishunqi  
       2019-06-12 20:59:57 +08:00 via iPhone
    就是 b
    africwildman
        6
    africwildman  
       2019-06-12 21:02:00 +08:00
    容易绕进去的代码还是用括号括一下保险。
    anyele
        7
    anyele  
       2019-06-12 21:04:00 +08:00 via Android   2
    并不是 Java 的坑,是你写出来坑自己,坑别人
    CEBBCAT
        8
    CEBBCAT  
       2019-06-12 21:28:53 +08:00   1
    虽然我算对了数了,但还是被标题偏进来了的,楼主你赢了
    luozic
        9
    luozic  
       2019-06-12 21:38:04 +08:00 via iPhone
    括号不用?
    Takamine
        10
    Takamine  
       2019-06-12 21:38:47 +08:00 via Android
    Java:这个锅我不背。

    如果对运算优先级不熟,请多加括号。:doge:
    iiii
        11
    iiii  
       2019-06-12 21:40:38 +08:00 via Android
    这能怪到 Java?
    potatowish
        12
    potatowish  
       2019-06-12 22:27:49 +08:00
    看到这么写代码的,我会过去打死他
    Leammin
        13
    Leammin  
       2019-06-12 22:30:12 +08:00 via Android
    idea 这样的有提示,我已经看到公司代码里好几处这样的写法了
    Navee
        14
    Navee  
       2019-06-12 22:47:41 +08:00
    这不是语言的坑,你这个写法就有歧义
    xrlin
        15
    xrlin  
       2019-06-12 22:52:03 +08:00
    上一个这么写的已经被拖去打靶了
    Ahaochan
        16
    Ahaochan  
       2019-06-12 22:57:25 +08:00
    int i = 0;
    System.out.println(i++ + ++i + ++i);
    请(
    itechify
        17
    itechify  
    PRO
       2019-06-12 23:08:16 +08:00 via Android
    为啥不用括号。。。
    vanhukset
        18
    vanhukset  
       2019-06-12 23:08:30 +08:00
    代码没有这么写的
    Kilerd
        19
    Kilerd  
       2019-06-12 23:42:23 +08:00 via iPhone
    首先代码不会这么写,其次空格强行干扰优先级判断
    Vegetable
        20
    Vegetable  
       2019-06-12 23:56:39 +08:00
    同一行,多个运算符时,除非各个运算符的优先级明显相同,也就是连续+-,连续* /,或者连续 and or 时,我才不用括号,否则为了可读性也要加上括号,这导致我其实对各个语言的运算符优先级都没什么认识,我需要优先级高的都用括号了
    cheng6563
        21
    cheng6563  
       2019-06-13 00:31:21 +08:00 via iPhone
    还真没遇到
    int b=2;
    int a=b=3;
    结果不是很清晰的?
    silentstorm
        22
    silentstorm  
       2019-06-13 06:27:00 +08:00 via Android
    神经病才这么写代码,纯属跟自己过不去。
    kevinWHX
        23
    kevinWHX  
       2019-06-13 07:08:52 +08:00 via iPhone
    按照大类,算数运算符 比较运算符 逻辑运算符 优先级依次降低
    gramyang
        24
    gramyang  
       2019-06-13 07:25:12 +08:00
    一般来说,烦了这个错误,悄悄的不做声,或者说自己看错了,然后下次改正就行了。。。。

    理直气壮的说出来小心被优化啊
    wozhizui
        25
    wozhizui  
       2019-06-13 07:47:15 +08:00
    有记和查运算优先级的时间,还不如加个括号,这哪是什么坑。
    另外,我读的时候就是 b 啊。
    Java 应该是最稳的老狗语言了。
    AlphaStone
        26
    AlphaStone  
       2019-06-13 08:02:33 +08:00
    没踩到,看一眼就知道是 b
    sonyxperia
        27
    sonyxperia  
       2019-06-13 08:23:00 +08:00
    我从来都是用括号的,记什么优先级
    cway
        28
    cway  
       2019-06-13 09:07:37 +08:00
    肯定是 b 啊,搁谁第一眼都差不多是,没括号 a + "_" + b 就是一个整体
    passerbytiny
        29
    passerbytiny  
       2019-06-13 09:10:28 +08:00
    格式化后的代码:
    String a = "a";

    String b = "b";

    String c = a + "_" + b == null ? "" : b;

    有时间破坏格式化,没时间加括号。
    HENQIGUAI
        30
    HENQIGUAI  
       2019-06-13 09:12:34 +08:00
    没加括号,空格也不好好用,规范都读哪儿去了?
    palmers
        31
    palmers  
       2019-06-13 09:12:42 +08:00
    Sornets
        32
    Sornets  
       2019-06-13 09:15:53 +08:00
    面试最烦碰见这种 xx 题
    simonv3ex
        33
    simonv3ex  
       2019-06-13 09:16:31 +08:00   1
    a + "_" + b 就不等于 null 啊,所以结果是 b
    lyy16384
        34
    lyy16384  
       2019-06-13 09:17:21 +08:00
    @Vegetable #20 关系运算符之间也有优先级的吧
    pkookp8
        35
    pkookp8  
       2019-06-13 09:19:49 +08:00 via Android
    错觉来自于空格,请加上空格再看一遍
    还有错觉搜索一下运算符优先级对着再看一遍
    如果懒得看随便找一种语言跑一下这段代码,结果都一样
    calming
        36
    calming  
       2019-06-13 09:21:33 +08:00
    写这种代码自己心里过得去?
    460881773
        37
    460881773  
       2019-06-13 09:22:55 +08:00
    对不起 一下子就算出是 b
    yaoper
        38
    yaoper  
       2019-06-13 09:23:18 +08:00
    自己造作的坑。
    itmyhome126
        39
    itmyhome126  
       2019-06-13 09:28:30 +08:00
    这不是基础问题吗。。
    zifangsky
        40
    zifangsky  
       2019-06-13 10:00:37 +08:00
    如果对运算优先级不熟,请多加括号!
    jinksw
        41
    jinksw  
       2019-06-13 10:10:05 +08:00
    遇到过这个问题 一下就记住了 遇到之前 跟你想的一样
    szq8014
        42
    szq8014  
       2019-06-13 10:10:34 +08:00
    这并不是坑,而是脑子有泡
    ctsua
        43
    ctsua  
       2019-06-13 10:14:46 +08:00
    不就是个三目吗
    Banxiaozhuan
        44
    Banxiaozhuan  
       2019-06-13 10:20:00 +08:00
    小学生?
    ipwx
        45
    ipwx  
       2019-06-13 10:30:00 +08:00
    不同优先级的运算符混用永远加括号。小学生都会的操作。。。
    tonyli
        46
    tonyli  
       2019-06-13 10:41:17 +08:00
    就是 b 啊,没毛病啊!
    ruok
        47
    ruok  
       2019-06-13 10:43:03 +08:00
    iccfish
        48
    iccfish  
       2019-06-13 10:48:03 +08:00
    这算啥坑,这是自己不懂吧。
    FrankHB
        49
    FrankHB  
       2019-06-13 13:17:49 +08:00   1
    当优先级这种智熄设计遇到了 zz 用户就是这样个下场……
    被幼稚园数学毒害的中缀破烂语法扔了哪来那么多破事。
    matthewxu123
        50
    matthewxu123  
       2019-06-13 13:24:09 +08:00
    初级题
    beidounanxizi
        51
    beidounanxizi  
       2019-06-13 13:25:03 +08:00 via iPhone
    go 就摒弃了这点
    zsy979
        52
    zsy979  
       2019-06-13 13:29:16 +08:00
    为什么会以为是 "a_b"呢?
    pmispig
        53
    pmispig  
       2019-06-13 14:43:31 +08:00
    写这种代码的人还是早点开除吧
    jamesliu96
        54
    jamesliu96  
       2019-06-13 14:47:43 +08:00 via Android
    佛了,返校重修吧
    fxplay
        55
    fxplay  
       2019-06-13 15:03:28 +08:00   1
    @zsy979
    他想的应该是这样的。
    String a = "a";

    String b = "b";

    String c = a + "_" +( b==null?"":b);
    IllllI
        56
    IllllI  
       2019-06-13 16:23:42 +08:00
    你这写的就是 B 你想表达什么 直说
    sesmond
        57
    sesmond  
       2019-06-13 16:32:38 +08:00
    我想说加个括号会 X 吗
    KannaMakino
        58
    KannaMakino  
       2019-06-13 18:10:44 +08:00 via iPhone
    还好吧,不过这么写有毒
    way2create
        59
    way2create  
       2019-06-13 18:23:21 +08:00
    ...这种不叫坑吧 就是运算符优先级的问题,只能说基础不牢又不爱加括号了,我也经常忘,所以我加括号
    flyingghost
        60
    flyingghost  
       2019-06-13 18:31:53 +08:00
    说实话,这个“坑”字的定义有问题。
    坑,常用来描述反常理的,有 bug 的,太 trick 绝大多数人都不知道的旮旯。之所以是坑,就是绝大多数人都会掉进去。
    而运算符优先级,既是常理,又没 bug,也一点 trick 都没有。这不是坑,这是基础知识存在盲点,是个人问题。
    flyingghost
        61
    flyingghost  
       2019-06-13 18:34:48 +08:00
    另一个话题,虽然对于运算符优先级我就从来没记清过,但印象里凡是自带?:三目运算符的语言,好像都是超低优先级,都是排在+-*/之后。
    所知语言有限,实在想不起例外。我尽力了。
    jptx
        62
    jptx  
       2019-06-13 19:15:31 +08:00
    如果对这种运算符优先级不熟悉的话,直接一把括号走天下
    HunterPan
        63
    HunterPan  
       2019-06-13 19:28:58 +08:00
    这样写 打死你,这是对别人负责
    alikesi
        64
    alikesi  
       2019-06-13 19:29:48 +08:00 via Android
    不用括号依靠记忆优先级和用汇编写代码有什么区别?
    liuxey
        65
    liuxey  
       2019-06-13 19:32:26 +08:00
    你是我看到的第 N 个基础不牢,被三目“坑”的程序员
    FrankHB
        66
    FrankHB  
       2019-06-13 23:57:34 +08:00
    @flyingghost 我发现所谓的优先级除了一个模棱两可的技术优势,剩下可以说毫无意义,全是跟风:因为历史既有以及别人习惯了这个设计,所以我也要用适应这种设计,即便根本说不清楚习惯是怎么来的,有哪些合理性。
    这就是坑。反过来,分析清楚为什么这是个烂设计的思路,才是基础知识。
    当然,你可以试着想想一下优点是什么,再做结论。
    flyingghost
        67
    flyingghost  
       2019-06-26 00:11:28 +08:00
    @FrankHB 说分析就分析。
    不要思考,不要先验,不要预定义优先级。如果我们引入了?:运算符来简化 if/else,来试试凭直觉猜测以下 y=f(x)函数的意图。

    y = x >= 0 ? 0 : 1
    猜它是想干嘛?
    A,三目运算符具有高优先级。y = x >= (0 ? 0 : 1) => y = x >= 1 => 根据 x 是否大于等于 1 得到 bool 值。这个例子中 (0 ? 0 : 1) 表达式其实非常不稳定,条件为 0 则永假,条件为非 0 则永真,在 int 不能自动转型 bool 的强类型语言中则直接挂。
    B,三目运算符具有低优先级。y = (x >= 0) ? 0 : 1 => 根据 x 是否大于等于 0 得到 y 为 x 的符号位 0 或 1。
    显然方案 B 容易理解比较合理并且稳定可预期。结论 1:三目运算符优先级低于比较运算符。

    再来一个。
    y = condition ? x : x +1
    猜它是想干嘛?
    A,三目运算符具有高优先级。y = (condition ? x : x) +1 => y = x + 1,condition 在这里毫无意义。
    B,三目运算符具有低优先级。y = condition ? x : (x+1) ,条件成立则 y=x,否则 y=x+1。
    显然方案 B 容易理解比较直观。结论 2:三目运算符优先级低于+加法双目运算符。

    这样的例子还可以举下去。
    我不知道大师们在设计语言的时候是否有类似的心路历程,但以我粗浅直观的感受来说,我对三目运算符优先级如此之低表示非常舒适非常满意。
    FrankHB
        68
    FrankHB  
       2019-06-26 20:19:52 +08:00
    @flyingghost 你搞错了重点。我并没有说现在三目操作符的低优先级不合理,而是存在固定数量操作数的 ad-hoc 中缀语法整个就应该砍掉,这样根本就不需要纠结这样的问题了。

    cf. github.com/FrankHB/pl-docs/blob/master/zh-CN/about-syntax.md

    顺便,三目操作符实际是有你没提到的特别坑的地方的:??::嵌套。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2523 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 15:03 PVG 23:03 LAX 08:03 JFK 11:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86