跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Java :如何处理空指针?
未分類
24 2 月 2020

Java :如何处理空指针?

Java :如何处理空指针?

資深大佬 : sandman511 51

Integer code = getCode(); String codeMeaning = code == null ? null :                     code == 1 ? "你好" :                     code == 2 ? "你好好" :                     code == 3 ? "你好好好"; 

请各大佬帮忙修改这段代码
code == null ? null 看起来有点怪怪的

大佬有話說 (57)

  • 資深大佬 : avk458

    三元表达式还能这样玩儿?
    按照这个`codeMeaning`的意思来用 switch 是不是更好?
    包装类比较是不是应该用 equals ?

  • 資深大佬 : pmispig

    谁写的,先把他头锤爆

  • 資深大佬 : Lin0936

    // TODO: Bullshit

  • 主 資深大佬 : sandman511

    @pmispig 实不相瞒。。我写的。。

  • 資深大佬 : manami

    Objects.equals(a, b)

  • 資深大佬 : optional

    // 第一种提前返回
    “`
    if (Objects.isNull(code)) {
    return null;
    }
    //switch or if
    “`
    //第二种,
    “`
    Optional.ofNullable(code).map(code->{
    //switch or if
    }).orElse(null);
    “`

  • 資深大佬 : passerbytiny

    一,Java 没有指针;
    二,三元连接符嵌套使用是大忌;
    三,if(some == null) { //bulabula when null }else{ //bulabula when not null},或者 if(some != null){bulabula},或者 some.ifPresent((value)->{/bulabula}), 是良好的编码习惯;
    四,请善用默认值:
    Integer code = getCode();
    String codeMeaning == null ;// 或者 “默认值”
    if(code != null){
    switch (code.intValue()){
    case 1 : codeMeaning = “你好”; break;
    // ……
    }
    }

  • 主 資深大佬 : sandman511

    @avk458 我嫌 switch 写起来太麻烦了 这个逻辑比较简单 就三行 所以用了三元。。。请教一下三元不能这样用吗?
    确实该用 equals,但是 code 可能为 null,equals 可能抛空指针。。所以不知道该咋办了

  • 資深大佬 : lff0305

    “`
    Optional<Integer> code = Optional.ofNullable(getCode());
    String s = code.map(c -> {
    switch (c) {
    case 1: return “one”;
    case 2: return “two”;
    }
    return “other”;
    }).orElse(null);
    “`

  • 資深大佬 : ily433664

    Map<Integer, String> map = new ….
    codeMeaning = map.get(code);

  • 資深大佬 : littleylv

    实不相瞒,三元这么嵌套不加括号的,除了傻逼笔试题外,工作中这样写的同事我会打死他(不是不能嵌套,你得加括号增加可读性)

  • 資深大佬 : lihongjie0209

    不加括号就是作死

  • 資深大佬 : w292614191

    我感觉比上那些 if else switch 好看多了。

    都是些秀无意义代码的。

    你看看 7、9 ,

    硬是加长代码,毫无意义。

  • 資深大佬 : Jimmy2Angel

    @passerbytiny 一,你真是个合格的杠精

  • 資深大佬 : ipwx

    private static final String[] lookup = {null, “你好”, “你好好”, “你好好好”};
    String codeMeaning = lookup[code != null? code.intValue() : 0];

    https://ideone.com/7rXSyK

  • 資深大佬 : matepi

    enum 特性都多少年了吧

  • 資深大佬 : banmuyutian

    @w292614191
    “硬是加长代码,毫无意义。”?
    等你看到那些难以阅读维护的代码就知道代码规范的重要性了

  • 資深大佬 : micean

    挺清晰的,加啥括号?有换行和缩进还不够吗?

  • 資深大佬 : lhx2008

    enum 吧,或者 map
    code 的话,null 就整个-1 呗,null 来 null 去的

  • 資深大佬 : wysnylc

    optional+switch,或者用 java 13 还是 14 的新 switch

  • 資深大佬 : kkkkkrua

    switch 不就好了么,用 default 处理 null

  • 資深大佬 : sagaxu

    应该用 int,避免 Integer,code 增加一项表示原来用 null 表示的情况。其实用 enum 不是更好吗?

  • 資深大佬 : Sqpan2

    做个枚举不香吗?

  • 主 資深大佬 : sandman511

    @Sqpan2
    @sagaxu
    @lhx2008
    @matepi
    不能用枚举哈,因为 code=1 不一定代表就是”你好“ 只是在这个地方等于”你好”
    在另一个方法里可能就是”你好好好“
    除非创建 7、8 个枚举类,每个枚举类中就三个参数。。

  • 資深大佬 : oneisall8955

    var table=new HashMap<Integer,String>(){
    {
    put(k1,v1);
    put(k2,v2);
    // …
    }
    };

    table.get(xx)

  • 資深大佬 : zzzHas

    如果能提高阅读性, 代码长点就长点.

  • 資深大佬 : looseChen

    别特么的玩些花里胡哨的玩意

  • 資深大佬 : wesnow

    代码更容易阅读比代码的长短重要得多,甚至可以说除非是非常极端的情况(比如有个地方确实对性能要求很高,这里就可能牺牲部分阅读性),否则都应该把代码更容易阅读更容易理解放在第一位。

  • 資深大佬 : qyvlik

    @ipwx #15 这种查表法可还行。省去 if, switch 的逻辑判断。

  • 資深大佬 : wc951

    java8 的 optional 是最优雅的

  • 資深大佬 : 1et

    int a = 1,b=2,c=3;
    int d = a+++b+++c;

  • 資深大佬 : palmers

    按照你回复的#24 我觉得可以使用枚举区分调用类别, 然后返回字符串抽象为方法 应该可以达到你的目的, 这么用确实不太好 除了秀也没有达到简洁的目的, 维护会越来越乱 临时用一下就没什么了
    不知道你真是的需求是什么 就目前你暴露的意愿 我觉得 枚举+抽象可以很好的解决这个问题 也符合开闭原则

  • 資深大佬 : ymz

    @kkkkkrua null 的话报空指针错误,到不了 default

  • 資深大佬 : guyeu

    String result = switch (Objects.requireNonNullElse(code, 0)) {
    case 0 -> null;
    case 1 -> “你好”;
    case 2 -> “你好好”;
    case 3 -> “你好好好”;
    default -> throw new UnsupportedOperationException();
    };

  • 資深大佬 : kkkkkrua

    @ymz #33 学到了,谢谢

  • 資深大佬 : hhhsuan

    代码的首要作用是给人看,只是随便可以运行一下。

  • 資深大佬 : oaix

    Optional 一般只建议用在方法的返回值。

  • 資深大佬 : ilumer

    optional+enum 或者 optional+map 在 map 里面写 if else 的逻辑

  • 主 資深大佬 : sandman511

    @palmers 我又在主贴 APPEND 了一下真正的需求

  • 資深大佬 : earther01

    @oaix 为啥呢,是效率不高吗?

  • 資深大佬 : oaix

    @earther01 不直观。
    https://dzone.com/articles/using-optional-correctly-is-not-optional 第 12 条

  • 資深大佬 : wutiantong

    从 append 的代码来看,你应该把 Integer unit + String transferredUnit 这两样东西 wrap 成一个简单的 class,不妨就还叫 unit 好了,数字和字符串作为 unit 这个 class 的两个成员属性。

    你的 getUnit(type) 应该直接返回这个 unit class。

  • 資深大佬 : palmers

    public enum UnitOfWeight {
    KG(“kg”) {
    @Override
    public boolean match(int unit) {
    return false;
    }
    },
    GRAM(“g”) {
    @Override
    public boolean match(int unit) {
    return false;
    }
    },
    TON(“t”) {
    @Override
    public boolean match(int unit) {
    return false;
    }
    },
    UNKNOWN(“x-0”){
    @Override
    public boolean match(int unit) {
    return false;
    }

    @Override
    public boolean unknown() {
    return true;
    }
    };

    /**
    * e.g. kg, g, t
    */
    @Getter
    private String note;

    static UnitOfWeight[] units = UnitOfWeight.values();

    /**
    * kg’s enums
    */
    static int[] kgs = {1, -1, 4};
    /**
    * gram’s enums
    */
    static int[] grams = {2, 0, 5};
    /**
    * ton’s enums
    */
    static int[] tons = {3, 1, 6};

    UnitOfWeight(String note) {
    this.note = note;
    }

    public static UnitOfWeight valueOf(Integer unit) {
    for (UnitOfWeight ofWeight : units) {
    if (unit == null) {
    return UNKNOWN;
    }
    if (ofWeight.match(unit)) {
    return ofWeight;
    }
    }
    return UNKNOWN;
    }

    /**
    * 获取对应枚举
    * @param unit
    * @return
    */
    public abstract boolean match(int unit);

    /**
    * 错误的值
    * @return
    */
    public boolean unknown() {
    return false;
    }

    public static void main(String[] args) {
    Integer unit = null;
    //getUnit (type2);
    UnitOfWeight ofWeight = UnitOfWeight.valueOf(unit);
    if (!ofWeight.unknown()) {
    String transferredUnit = ofWeight.getNote();
    //…
    }
    }
    }

    根据你 append 的代码用了一个枚举来做, 根据你的描述我想有几个点需要扩展,
    1. 从 pdf 解析 type 值;
    2. 有很多情况(可能因为历史原因很多地方使用了不同的值代表某一个单位);
    所以我建议使用枚举, 原因是:
    1. 我觉得后面随着业务需要或者其他原因重构, 可能慢慢的这些代表某一个单位的值会改变或者统一为一个,所以你需要修改 通过枚举可以统一在一处,便于修改;
    2. 再者也方便返回的字符值变更 总之对于变更这个枚举类基本上可以应对 90%以上的情况;
    3. match 方法可以做针对行的扩展和优化;

  • 資深大佬 : boileryao

    “`java
    // Put this map somewhere
    Map<Integer, String> codeMeaningInfo = new HashMap<>();
    codeMeaningInfo.put(1, “你好”);
    codeMeaningInfo.put(2, “你好好”);
    codeMeaningInfo.put(3, “你好好好”);

    // Using this map
    String codeMeaning = codeMeaningInfo.get(code);
    “`
    一般情况下 Map 应该全局唯一,另外推荐 Kotlin 的 `when` 表达式。

  • 資深大佬 : loryyang

    可以的话,尽量不要用 null,容易在各种传递运算中出现空指针异常。比如你这个 code 和 codeMeaning,code=-1,codeMeaning=“”表示异常。甚至可以用 Enum 来包装这些内容
    如果硬是要用 null,我建议把 null 的处理和其他处理分开。尽量不要用三元表达式,这种东西比较反人类,写起来很爽,看起来一头包。
    你这种情况可以写个函数 getCodeMeaning(Integer code) {
    if (code == null) {
    return null;
    } else if (code == 1) {
    ******
    }
    代码在可读可维护性面前,简洁性可以要求低一些

  • 資深大佬 : luozic

    如果 java 有 pattern match 就可以玩优雅;但是 Java 没有,所以,理智一点,用表驱动去糊弄算了。

  • 資深大佬 : redford42

    前几天看到一个 java8 的 optional
    但其实我没看太明白…

  • 資深大佬 : loryyang

    @loryyang #45 另外还有一个避免魔法值,前面也好多人提了。对于这一点,我是觉得,你考虑一下是否有必要做。你这种 case,直接用一个 ImmutableMap 好了,这样可以变成:
    ImmutableMap.<Integer, String>builder().put(1, “”).put(2, “”).build()
    然后 getCodeMeaning 函数里面变成
    if (code == null) {
    return null;
    }
    if (code in immutableMap) {
    return immutableMap.get(code);
    }
    else {
    return ***;
    }

    回头看一下,还是 null 太多了,null 这东西还是不要在正常流程中出现吧

  • 資深大佬 : nekoneko

    @redford42 #47 感觉 optional 就是婊子立牌坊

  • 資深大佬 : godoway

    @nekoneko
    @redford42
    这其实是语法上提醒你检测空安全,例如有个接口入参 optional,你就知道这里可能为空,入参一个对象有可能你就忘了检测非空

  • 資深大佬 : godloveplay

    你写的代码是给别人看的。 请你站在别人的角度思考一下,看到这个代码的心情

  • 資深大佬 : oneisall8955

    @nekoneko 深层嵌套获取值,一直判断非空很啰嗦,Optional 可以解决这个问题

  • 資深大佬 : winiex

    永远不要嵌套多层三元表达式,三元表达式当且仅当只有一层逻辑判断时才可以使用。其它情况一律用 if else 老实地写。我甚至连一层逻辑判断都想强制只能用 if else。

  • 資深大佬 : brucefu

    @micean 能让别人一秒就看懂的东西,就不要搞成两秒

  • 資深大佬 : micean

    @brucefu

    code == null ? null :
    code == 1 ? “你好” :
    code == 2 ? “你好好” :
    code == 3 ? “你好好好” :
    “其他”;

    这不就是一个简易秒懂的 switch,上其他代码也做不到这么工整

  • 資深大佬 : micean

    另外嵌套的三元还可以轻轻松松给 final 修饰的赋值

    final String name =

    code == null ? “” :
    code == 1 ? “你好” :
    code == 2 ? “你好好” :
    code == 3 ? “你好好好” :
    “其他”;

  • 資深大佬 : secondwtq

    这不就是一个 Maybe Integer 解决的问题 … 搞这么复杂

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具