2011-07-11 51 views

回答

160
  • private - 使其他类可以劫持您记录
  • static - 所以只有一个每个类的记录器实例,也避免试图序列记录器
  • final - 无需改变日志记录器

此外,我更喜欢名称log尽可能简单,但描述性。

编辑:但是还有一个有趣的例外规则:

protected final Logger log = LoggerFactory.getLogger(getClass()); 

,而不是:

private static final Logger log = LoggerFactory.getLogger(Foo.class); 

前者的方法可以让你使用相同的记录器名称(实际名称类)遍历继承层次结构中的所有类。因此,如果Bar延伸Foo,则两者都将登录到Bar记录器。有些人觉得更直观。

+0

+1,答案在修饰符中。 – mre

+24

if static and final then LOG(大写) – zacheusz

+29

* @ zacheusz *,我知道这就是要点。一些人虔诚地遵循Java命名约定(没有什么不妥),但我更愿意写和更愉快的阅读'log'名称,而不是用'LOG'分散代码。只是开发的问题。团队协议。 –

2

什么时候你想改变字段的值?

如果你永远不会改变这个值,那么使得这个字段最终成为明显的,你永远不会改变它的值。

+1

在很多情况下,显然不添加final这个词,它就会变成一种垃圾。 – Dima

+0

@Dima:那么我仍然感激编译器仍然会抛出一个错误,如果我*不小心尝试在这些情况下尝试更改值... –

2

因为这通常是可以在您的对象的所有实例中共享的那种功能。对于同一类的两个实例有不同的记录器没有太大意义(90%的时间)。

但是,你也可以看到声明为单身人士甚至干脆提供静态函数来记录你的东西,有时记录器类。

1

通常你初始化记录器使用类名进行登录 - 这意味着,如果他们不是一成不变的,你最终会具有它的一个实例(高内存占用)类的每个实例,但所有这些记录器将共享相同的配置并且行为完全相同。这就是static位背后的原因。此外,因为每个Logger被初始化与类名,以防止与子类冲突,声明它private所以它不能被继承。 的final来自于你不应该在执行过程中改变Logger点 - 所以一旦初始化你永远不会“重新配置”它 - 在这种情况下,它是有道理的,使其最终确保无人可换它(通过错误或其他方式)。 当然,如果您打算以不同的方式使用Logger,您可能需要而不是以使用static final - 但我敢说大概猜测80%的应用程序会使用日志记录,如上所述。

4

static意味着你只能创建每类中的一个记录器,每实例类的没有一个记录器。一般来说,这就是你想要的 - 因为伐木者往往只根据班级而变化。

final表示您不打算更改logger变量的值。这是真的,因为你几乎总是把所有的日志消息(从一个类)扔到同一个记录器。即使在极少数情况下,类可能想要将某些消息发送到不同的记录器,但创建另一个记录器变量(例如widgetDetailLogger)会更清晰,而不是通过动态地变更静态变量的值。

0

在大多数情况下,您将要更改该值,final修饰符会将其标记。对于每个类实例,您不需要单独的实例 - 因此static首先这是为了性能 - 它可以很好地优化(最终)并保存内存(静态)。

3

要回答这个问题,你应该问自己什么是“静态”和“最终”。

对于Logger,(我假设你谈论Log4J Logger类),你需要每个类的类别。这应该导致只分配一次的事实,并且每个类不需要多个实例。大概没有理由将一个类的Logger对象暴露给另一个类,为什么不把它设为私有并遵循一些面向对象原则。

另外你应该注意,编译器能够从中受益。所以你的代码执行更好一点:)

7

检查此博文:Get Rid of Java Static Loggers。这是你如何使用SLF4J与jcabi-log

import com.jcabi.log.Logger; 
class Foo { 
    void save(File f) { 
    Logger.info(this, "file %s saved successfully", f); 
    } 
} 

而且从来没有使用静态噪声了。

+0

一个有趣的选择,绝对清洁。我想知道这与个人班级记录员相比如何。 – Ross

+5

每次写更长的记录器..(this,...)。罗。 –

0

除了其他答案一两件事,我跑进是给出的理由是,如果我的记录既不是静态的也不是最后:

... 
public Logger logger = LoggerFactory.getLogger(DataSummary.class); 

public String toJson() { 
    GsonBuilder gsonBuilder = new GsonBuilder(); 
    return gsonBuilder.create().toJsonTree(this).toString(); 
} 
... 
在某些情况下

(我用的是GSON库)我会得到stackoverflow异常。我的具体情况是实例化包含非静态非最终记录器的类。然后调用的toJSON方法,它调用GsonBuilder:

... 
DataSummary ds = new DataSummary(data);  
System.out.println(ds.toJson()); 
... 
1

此代码是脆弱的,但Java7后,我们就可以使用Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); ,而不是静态的记录。

相关问题