用于共享使用的静态与实例方法

时间:2022-02-01 16:54:41

Here's what I am trying to determine...

这是我想要确定的......

I have a utility class to append lines to a text file. This must be used by a number of other classes, like a common logging file.

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

In my first implementation, I had all the classes that wanted to use it make a reference-less instance, e.g.

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

new Logger(logline,logname);

The constructor creates a PrintWriter, appends the line and closes the file.

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

This seemed wasteful, since a new instance gets made for every line appended.

这似乎很浪费,因为每个附加的行都会生成一个新实例。

The alternative was to use a static method, called "writeln" in this common class, since I had understood that static methods and data re-use the same memory over & over...but

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

this static method creates an instance of PrintWriter to do its job, so doesn't that mean that a new instance of PrintWriter is created for every line, like #1?

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

Anyway, (I am relatively new to Java ) is there a well-known, approved way of doing this, or do we just create away, and let the garbage-collector clean up after us?

无论如何,(我相对较新的Java)有一个众所周知的,批准的方式,或者我们只是创建,让垃圾收集器清理后我们?

Thanks

3 个解决方案

#1


The sensible answer is that you should use a "serious" logging package, such as Commons Logging.

明智的答案是你应该使用“严重”的日志包,例如Commons Logging。

However, to answer your question, in this case you should use a static method (unless you're wanting to maintain logging class instances in your code, in which case you should follow the other answers in this thread). Additionally, you should have a static field that's initialised to, say, a Map<String, PrintWriter>. (You don't have to use String as the key: if you want a finite number of logging target types, use an enum.)

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

Then, when your method sees a key that's not existent in the map yet, it'd create the PrintWriter on the spot, and sticks it in the map. You probably want to use a ConcurrentHashMap as the backing map type, so it's thread-safe.

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

You also need to provide a way to close a logging target (which will also clear the associated entry from the map).

您还需要提供一种关闭日志记录目标的方法(它还将清除映射中的相关条目)。

Good luck!

#2


You shouldn't be doing any work in your contructor.

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

Constructors are for object setup.

构造函数用于对象设置。

You should create a Log() method to do the actual logging.

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

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

or you can setup the logger as a Singleton.

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

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

Singleton Pattern in Java: http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

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

#3


There are several kinds of state that this object might want to hold onto, particularly the PrintWriter. If your Logger class were to store these as instance data, then the method for doing the logging needs to be an instance method, not a static method. Hence you need to separate out the logging from the construction:

此对象可能需要保留几种状态,尤其是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.");

I haven't shown any of the implementation details, but I hope this is enough to get you going.

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

#1


The sensible answer is that you should use a "serious" logging package, such as Commons Logging.

明智的答案是你应该使用“严重”的日志包,例如Commons Logging。

However, to answer your question, in this case you should use a static method (unless you're wanting to maintain logging class instances in your code, in which case you should follow the other answers in this thread). Additionally, you should have a static field that's initialised to, say, a Map<String, PrintWriter>. (You don't have to use String as the key: if you want a finite number of logging target types, use an enum.)

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

Then, when your method sees a key that's not existent in the map yet, it'd create the PrintWriter on the spot, and sticks it in the map. You probably want to use a ConcurrentHashMap as the backing map type, so it's thread-safe.

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

You also need to provide a way to close a logging target (which will also clear the associated entry from the map).

您还需要提供一种关闭日志记录目标的方法(它还将清除映射中的相关条目)。

Good luck!

#2


You shouldn't be doing any work in your contructor.

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

Constructors are for object setup.

构造函数用于对象设置。

You should create a Log() method to do the actual logging.

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

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

or you can setup the logger as a Singleton.

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

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

Singleton Pattern in Java: http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

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

#3


There are several kinds of state that this object might want to hold onto, particularly the PrintWriter. If your Logger class were to store these as instance data, then the method for doing the logging needs to be an instance method, not a static method. Hence you need to separate out the logging from the construction:

此对象可能需要保留几种状态,尤其是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.");

I haven't shown any of the implementation details, but I hope this is enough to get you going.

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