用于日志记录的 Java 枚举

标签 java logging enums

我是 Java 新手,正在测试现有项目的一些代码。我想知道为什么他们选择使用 枚举 作为日志消息。有什么提示吗?这是一个好方法吗?

这是包含日志消息的类:

import com.myproject.logging.LogEntryDefinition;

import java.text.MessageFormat;
import java.util.logging.Level;

public enum LogEntries implements LogEntryDefinition {

    MsgProcessingError( Level.SEVERE, "RPS0001", "Exception during message processing: {0}. Message consumed: {1}" ),
    MessageConsumedFromPcuQueue( Level.INFO, "RPS0002", "Message extracted from queue: {0}" ),
    ResourceRetrievedFromParis( Level.INFO, "RPS0003", "Resource retrieved from db: {0}" ),
    IllegalMessageConsumed( Level.SEVERE, "RPS0004", "Illegal update message consumed by Agent. Message: {0}" ),
    ...

    private final String id;
    private final MessageFormat format;
    private final Level level;

    private LogEntries( final Level level, final String id, final String format ) {
        this.level = level;
        this.id = id;
        this.format = new MessageFormat( format );
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public MessageFormat getFormat() {
        return format;
    }

    @Override
    public Level getLevel() {
        return level;
    }
}

这是界面:

package com.myproject.logging;

import java.text.MessageFormat;
import java.util.logging.Level;

public interface LogEntryDefinition {

    String getId();

    MessageFormat getFormat();

    Level getLevel();
}

这是一个如何使用它的示例:

...

}catch(Exception e){
    LOGGER.log( LogEntries.MsgProcessingError, e.getMessage(), t.toString() );
}

谢谢!

最佳答案

您建议他们应该在评论中使用单例。枚举是实现单例的一种更简单的方法。

枚举单例确保线程安全的初始化,而不需要双重检查锁定。这是 Initialize On-Demand idiom 的简单替代方案,虽然确保了线程安全的初始化而没有同步开销,但它非常冗长并且需要您创建一个帮助器类。

枚举单例还可以防止反射攻击。 单例只能存在一个实例(由于设计的性质)。使用基于类的单例,可以使用反射将构造函数的可访问性从 private 更改为 public,从而允许多个实例。枚举的构造函数是隐式私有(private)的,并且无法通过反射修改它的可访问性。

至于您对比较枚举与比较整数的评论,这被认为是微优化。您应该更多地关注可维护性,而不是试图节省几纳秒。

希望这能回答您的问题! :)

关于用于日志记录的 Java 枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36002113/

相关文章:

java - 在经典在线教程中找到正确的文件来构建 Android 项目

java - 在 Java 中如何访问命令行上提供的属性?

c - 在 C 中将变量记录到文件中

c# - 如何使用 SQL 显示字符串枚举值而不是数字值

java - 如何评估包含枚举值的json字符串?

java - spring-boot oauth2分离授权服务器和资源服务器

java - Java解析定宽文本日志的技巧

apache-flex - Flex 日志框架

java - 枚举感知的 ServiceLoader 实现?

c++ - 为什么枚举被认为是复合类型?