那些Java开发中遇到的问题

1. 日志打印使用占位符

1.1 占位符的作用

在日常开发中,为了方便问题定位,我们通常使用日志打印输出信息时。当程序出现了异常或者其他问题,需要通过日志来定位问题所在。

通常,我们在日志输出中会直接输出变量或者参数的值,那么在出现问题时,就更能准确地定位到关键点所在。

以下是常见的使用方式:

@Slf4j
public class Test2 {
    
    
    
    public static void main(String[] args) {
    
    
        cal(5);
        // cal(0)
    }/**
     * 计算100除以该数后等于多少
     * @param x
     */
    public static void cal(int x) {
    
    
        int result = 0;
        log.info("param: {}", x); //打印出相关参数
        try {
    
    
            result = 100/x;
            log.info("100 div {} = {}", x, result); //输出结果
        } catch (Exception e) {
    
    
            log.info("exception occur, exception: {}", e);
        }
    }
}

1.2 错误的使用占位符

上述的代码乍看之下没有问题,但是当我们传入参数0,查看日志打印结果:

image-20230414150318320

想要输出异常e时,e的信息确实打印了出来,但是占位符并没有被信息取代,这是为什么呢?

1.3 问题定位

image-20230414150438079

在idea中,也准确的给出了该问题的相关说明,这个错误的意思是:代码中的日志语句使用了一个占位符,但是在日志语句中并没有提供足够的参数来填充这个占位符

咦,可是我明明提供了参数e啊,为什么没用呢?

点进源码一看,恍然大悟。

image-20230414151122966

当传入的参数是异常类型时,就会直接走到日志打印逻辑,而不会进行占位符格式化处理。

1.4 正确用法

  • 可以不设置占位符,这样错误信息依旧会输出(推荐
catch (Exception e) {
    
    
    log.info("exception occur", e);
}

image-20230414151522024

  • 使用e.getMessage()方法,仅把异常类型的信息输出
catch (Exception e) {
    
    
    log.info("exception occur, excpetion: {}", e.getMessage());
}

image-20230414151709326

1.5 总结

当需要将异常信息输出到日志时,无需使用占位符 {},也能将异常信息完整打印出来。

2. finally中不要使用return

2.1 问题说明

image-20230413111732867

在阿里巴巴JAVA开发手册中有这么一条准则:

【强制】不要在finally块中使用return。
说明:finally块中的return返回后方法结束执行,不会再执行try块中的return语句。

以下是一个简单的代码示例:

@Slf4j
public class Test {
    
    
    public static void main(String[] args) {
    
    
        int result = testFinally();
        log.info("result is {}", result); // 输出结果为2而不是1
    }public static int testFinally() {
    
    
        int result = 0; // 初始化返回值变量
        try {
    
    
            result++;
            return result; // 返回语句
        } catch (Exception e) {
    
    
            log.info("exception occur.", e);
        } finally {
    
    
            // 在finally块中执行一些操作
            result++;
            return result; // 在方法的最后返回结果
        }
    }
}

打印结果如下:

image-20230414152809469

2.2 正确用法

@Slf4j
public class Test {
    
    
    public static void main(String[] args) {
    
    
        int result = testFinally();
        log.info("result is {}", result);
    }public static int testFinally() {
    
    
        int result = 0; // 初始化返回值变量
        try {
    
    
            result++;
        } catch (Exception e) {
    
    
            log.info("exception occur.", e);
        } finally {
    
    
            // 做一些清理资源或执行必要的清理操作
        }
        return result;
    }
}

2.3 补充说明

如果在try块和catch块中都没有返回值,那么在finally块中使用return语句并不会对程序产生任何影响。在这种情况下,finally块中的代码只会执行清理资源或执行必要的清理操作的任务,而不会影响函数或方法的返回值。

但是,即使在try块和catch块中没有返回值,还是应该避免在finally块中使用return语句。因为在finally块中使用return语句可能会给其他开发人员或维护人员带来困惑,并且不符合通常的编码惯例。

因此,建议尽可能避免在finally块中使用return语句,以保持代码的清晰度和可读性。

3. matches后再find

3.1 问题说明

某一天,我在进行日志匹配的时候,发现一段诡异的问题。明明我都匹配成功了,但是当我想取出关键信息时,却给我报了异常。

代码复现结果如下:

public class Test2 {
    public static void main(String[] args) {
        String str = "username:aaa";
        String regex = "username:(.*?)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        System.out.println("matches: " + matcher.matches()); // True
        System.out.println("find: " + matcher.find()); //false
    }
}

离了大谱,我明明都能匹配成功,却告诉我找不到匹配的信息?

3.2 问题定位

打上断点,可以很明显的看到,执行了matches方法后,match对象的内部参数值发生了变化。

image-20230414171801728

image-20230414171850331

点进find方法源码,我们可以看到,find方法查到的开始位置,就是last的值。

image-20230414172037243

matches()方法会将last的值置为字符串的长度,当执行find()方法时,模式匹配是从结尾处开始查找,而不是从输入序列的开头开始查找。因此,如果在Matcher对象上先调用matches方法,再调用find方法,可能会导致find方法无法找到任何匹配项。

3.3 解决办法

非常的简单,只需要使用find(0),重置查找其实位置即可。

public static void main(String[] args) {
    String str = "username:aaa";
    String regex = "username:(.*?)";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(str);
    System.out.println("matches: " + matcher.matches()); //True
    System.out.println("find: " + matcher.find(0)); //True
}

来自:那些Java开发中遇到的问题 - 掘金

猜你喜欢

转载自blog.csdn.net/qq_34626094/article/details/130176921