2

这是我要确定的...

我有一个实用程序类来将行附加到文本文件。这必须由许多其他类使用,例如公共日志文件。

在我的第一个实现中,我让所有想要使用它的类都创建了一个无引用实例,例如

new Logger(logline,logname);

构造函数创建一个PrintWriter,附加该行并关闭文件。

这似乎很浪费,因为每添加一行都会创建一个新实例。

另一种方法是在这个公共类中使用称为“writeln”的静态方法,因为我已经理解静态方法和数据会一遍又一遍地重复使用相同的内存......但是

这个静态方法创建一个实例PrintWriter 来完成它的工作,所以这是否意味着PrintWriter为每一行创建一个新实例,比如#1?

无论如何,(我对 Java 比较陌生)是否有一种众所周知的、被认可的方式来做到这一点,或者我们只是创建出来,然后让垃圾收集器在我们之后清理?

谢谢

4

3 回答 3

5

明智的答案是您应该使用“严肃的”日志记录包,例如Commons Logging

但是,要回答您的问题,在这种情况下,您应该使用静态方法(除非您想在代码中维护日志记录类实例,在这种情况下,您应该遵循此线程中的其他答案)。此外,您应该有一个静态字段,该字段已初始化为 a Map<String, PrintWriter>。(您不必String用作键:如果您想要有限数量的日志记录目标类型,请使用枚举。)

然后,当您的方法看到地图中尚不存在的键时,它会PrintWriter当场创建该键,并将其粘贴在地图中。您可能希望使用 aConcurrentHashMap作为支持映射类型,因此它是线程安全的。

您还需要提供一种关闭日志记录目标的方法(这也会从地图中清除相关条目)。

祝你好运!

于 2009-04-24T01:52:24.193 回答
3

你不应该在你的构造函数中做任何工作。

构造函数用于对象设置。

您应该创建一个 Log() 方法来执行实际的日志记录。

Logger l = new Logger();
l.Log(logline,logname);
l.Log(logline,logname);

或者您可以将记录器设置为单例。

Logger.getInstance().Log(logline, logname);

Java中的单例模式: http ://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

于 2009-04-24T01:48:56.323 回答
2

该对象可能希望保持多种状态,尤其是 PrintWriter。如果您的 Logger 类要将这些存储为实例数据,那么进行日志记录的方法需要是实例方法,而不是静态方法。因此,您需要将日志记录与构造分开:

// Pass only the PrintWriter into the constructor, not the line to be logged.
Logger myLogger = new Logger(filename);

...

// Log a message
myLogger.log("This is a message to be logged.");

// Log another message, just for kicks.
myLogger.log("this shows that myLogger can be used repeatedly.");

我没有展示任何实现细节,但我希望这足以让你继续前进。

于 2009-04-24T01:52:13.257 回答