Java :如何处理空指针?

2019-12-31 11:16:04 +08:00
 sandman511
Integer code = getCode();
String codeMeaning = code == null ? null :
                    code == 1 ? "你好" :
                    code == 2 ? "你好好" :
                    code == 3 ? "你好好好";

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

5819 次点击
所在节点    程序员
57 条回复
oaix
2019-12-31 14:47:05 +08:00
wutiantong
2019-12-31 14:50:57 +08:00
从 append 的代码来看,你应该把 Integer unit + String transferredUnit 这两样东西 wrap 成一个简单的 class,不妨就还叫 unit 好了,数字和字符串作为 unit 这个 class 的两个成员属性。

你的 getUnit(type) 应该直接返回这个 unit class。
palmers
2019-12-31 15:25:29 +08:00
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
2019-12-31 16:20:59 +08:00
```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
2019-12-31 16:22:23 +08:00
可以的话,尽量不要用 null,容易在各种传递运算中出现空指针异常。比如你这个 code 和 codeMeaning,code=-1,codeMeaning=“”表示异常。甚至可以用 Enum 来包装这些内容
如果硬是要用 null,我建议把 null 的处理和其他处理分开。尽量不要用三元表达式,这种东西比较反人类,写起来很爽,看起来一头包。
你这种情况可以写个函数 getCodeMeaning(Integer code) {
if (code == null) {
return null;
} else if (code == 1) {
******
}
代码在可读可维护性面前,简洁性可以要求低一些
luozic
2019-12-31 16:45:26 +08:00
如果 java 有 pattern match 就可以玩优雅;但是 Java 没有,所以,理智一点,用表驱动去糊弄算了。
redford42
2019-12-31 17:24:29 +08:00
前几天看到一个 java8 的 optional
但其实我没看太明白...
loryyang
2019-12-31 17:27:32 +08:00
@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
2019-12-31 17:33:15 +08:00
@redford42 #47 感觉 optional 就是婊子立牌坊
godoway
2019-12-31 18:16:00 +08:00
@nekoneko
@redford42
这其实是语法上提醒你检测空安全,例如有个接口入参 optional,你就知道这里可能为空,入参一个对象有可能你就忘了检测非空
godloveplay
2019-12-31 18:37:57 +08:00
你写的代码是给别人看的。 请你站在别人的角度思考一下,看到这个代码的心情
oneisall8955
2019-12-31 19:25:42 +08:00
@nekoneko 深层嵌套获取值,一直判断非空很啰嗦,Optional 可以解决这个问题
winiex
2020-01-01 11:15:47 +08:00
永远不要嵌套多层三元表达式,三元表达式当且仅当只有一层逻辑判断时才可以使用。其它情况一律用 if else 老实地写。我甚至连一层逻辑判断都想强制只能用 if else。
brucefu
2020-01-01 15:32:39 +08:00
@micean 能让别人一秒就看懂的东西,就不要搞成两秒
micean
2020-01-01 16:49:23 +08:00
@brucefu

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

这不就是一个简易秒懂的 switch,楼上其他代码也做不到这么工整
micean
2020-01-01 16:55:50 +08:00
另外嵌套的三元还可以轻轻松松给 final 修饰的赋值

final String name =

code == null ? "" :
code == 1 ? "你好" :
code == 2 ? "你好好" :
code == 3 ? "你好好好" :
"其他";
secondwtq
2020-01-01 18:31:04 +08:00
这不就是一个 Maybe Integer 解决的问题 ... 搞这么复杂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/633824

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX