当可能存在空指针时,如何避免冗余的 try-catch 语句?

How to avoid redundant try-catch statements when there might be null pointers?

我正在通过仔细查看 covid 跟踪应用程序来试验我在网上找到的“新”库。我扫描二维码,解码 base64 以获取 Json 字符串中的商店数据。然后我使用 Gson 解析成一个 Shop POJO。

public class Shop {
    public metadata metadata;
    public String nameZh;
    public String nameEn;
    public String type;
    public String hash;

    public class metadata{
        public String typeEn;
        public String typeZh;

        public String getTypeEn() { return this.typeEn; }
        public String getTypeZh() { return this.typeZh; }
    }

    public metadata getMetadata() { return this.metadata; }
    public String getNameZh() { return this.nameZh; }
    public String getNameEn() { return this.nameEn; }
    public String getType() { return this.type; }
    public String getHash() { return  this.hash; }
    public String toString() {
        return getMetadata().getTypeEn()+", "+getMetadata().getTypeZh()+", "
                +getNameZh()+", "+getNameEn()+", "+ getType()+", "+getHash();
    }
}
 

但是,当我想使用 apache POI 写入 excel 文件 (.xlsx) 时,我发现并非所有商店都有所有字段,这意味着有些字段为空。这是我得到的空指针异常。

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Shop$metadata.getTypeEn()" because the return value of "Shop.getMetadata()" is null
    at xlsxWorker.writeShop(xlsxWorker.java:77)
    at xlsxWorker.writeOutput(xlsxWorker.java:51)

虽然我可以使用 try catch 来避免这种情况,但生成的代码有很多 try catch。

private static void writeShop(Row current, Shop shop){
        Cell cell = current.createCell(0);
        try{
            cell.setCellValue(shop.getMetadata().getTypeEn());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
        cell = current.createCell(1);
        try{
            cell.setCellValue(shop.getMetadata().getTypeZh());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
        cell = current.createCell(2);
        try{
            cell.setCellValue(shop.getNameZh());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
        cell = current.createCell(3);
        try{
            cell.setCellValue(shop.getNameEn());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
        cell = current.createCell(4);
        try{
            cell.setCellValue(shop.getType());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
        cell = current.createCell(5);
        try{
            cell.setCellValue(shop.getHash());
        }catch (NullPointerException e){
            cell.setCellValue("null");
        }
    }

如何避免在这里过度使用try-catchs?如何简化冗余

您可以使用像

这样的默认值来初始化您的 Pojo
  1. 空字符串“”
  2. null 作为字符串文字“null”

更新

您也可以使用默认值创建新的元数据 或者使用这个例如

if(shop.getMetadata() != null)
{ 
//your brilliant code 
}

更新

'MapStruct' 可以帮你做地图

我会使用辅助方法:

private static void setCellValue_printNullOnNPE(Cell cell, Supplier<String> value){
    String text = "null";
    try{ 
        text = value.get()
    }catch(NullPointerException e){}
    cell.setCellValue( text );
}

那么您的 writeShop 方法将如下所示:

Cell cell = current.createCell(0);
setCellValue(cell, () -> shop.getMetadata().getTypeEn());
cell = current.createCell(1);
setCellValue(cell, () -> shop.getMetadata().getTypeZh());