Why some classes don't need the word “New” when creating its instance?
我是爪哇人。有一件事让我感到困惑,那就是为什么有些类需要
例如,我在看log4j,它不需要
1 2 3 | // get a logger instance named"com.foo" Logger logger = Logger.getLogger("com.foo"); logger.setLevel(Level.INFO); |
为什么其他的课程需要新的?例如,员工类:
1 2 | Employee X = new Employee (John); X.getwork(); |
等
为什么我们不说,以东十一〔三〕号?为什么即使没有
在Java中创建新对象的唯一方法是使用EDCOX1〔4〕〔1〕。但是,在某些类中,不允许您自己说
还要注意,您的示例可能根本不涉及新对象。
奥格登·纳什的以下诗句似乎有些关联:
1 2 3 4 5 | This morning I went to the zoo In order to look at the gnu. But the old gnu was dead, and the new gnu, they said, Was too new a new gnu to view. |
[1]除非你参与低层反射,或使用
在这种情况下,我们正在处理工厂方法,正如我在评论中所说的。
见
Retrieve a logger named according to the value of the name parameter. If the named logger already exists, then the existing instance will be returned. Otherwise, a new instance is created.
By default, loggers do not have a set level but inherit it from their neareast ancestor with a set level. This is one of the central features of log4j.
工厂方法模式是一种创造性的设计模式,根据维基百科,在以下情况下通常很有用:
The factory pattern can be used when:
- The creation of an object precludes its reuse without significant duplication of code.
- The creation of an object requires access to information or resources that should not be contained within the composing class.
- The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the application.
这三个都适用于…谁知道找到正确的记录器需要做什么工作?每次你想要使用一个新的日志记录程序时,你并不是真的有兴趣去创建一个全新的日志记录程序…相反,你的重点主要是——使用一个。
Creative Commons wiki也有一篇相关文章,
Factory methods are sometimes used in place of constructors for any of several reasons:
- Some languages (such as Java) do not allow constructors to have useful names
- Some languages (such as Java) do not allow constructors to have different names (which may be necessary if you want to use the same method signature for two constructors)
- To allow the same instance to be reused instead of recreated each time it is needed (see FlyweightPattern)
我认为第三种选择可能最适用于这里。使用手动创建新的
总而言之,使用工厂方法通常是为了在不公开您不必关心的工作的情况下实现更清晰、更直接的代码。
你所要求的与设计模式更相关。logger类遵循singleton模式。
假设您希望在应用程序中只创建类的一个实例,那么您可以将构造函数设置为私有的,并提供一个静态方法,该方法在第一次调用时创建和存储类的对象。
<代码>公共类单件模式{
1 2 3 4 5 6 7 8 9 10 11 | private static SingletonPattern instance; private SingletonPattern(){} public static synchronized SingletonPattern getInstance(){ if (instance == null){ instance = new SingletonPattern(); } return instance; } } |
通过这种方式,您可以限制类仅被实例化一次。
例如,某些类可能会阻止您在应用程序中创建多个对象。在这种情况下,您需要调用一些方法来实例化类,比如logger.getlogger()。getlogger()的代码如下:
1 2 3 4 5 | if(uniqueInstance == null) { uniqueInstance = new Logger(); } return uniqueInstance; |
其中uniqueinstance是logger的实例。这是一个名为singleton的设计模式。在这种模式中,不能实例化类,因为它的构造函数是私有的。
另一种无法实例化类的方法是将类定义为静态类。
具有公共构造函数且不是静态的类需要用new关键字实例化。
因为
1 2 3 4 5 | public class Logger { public static Logger getLogger() { return new Logger("foo","bar"); } } |
某些类不能在其自身之外进行实例化(例如,
1 2 3 4 | public class A { private A() {} public A createAnA() { return new A(); } } |
这里,
您没有在技术上使用logger类,而是在使用方法。您没有在技术上实例化logger类,也没有像使用
在您的示例中,您必须使用不同的用例:返回对象的静态方法和实际的构造函数调用。
静态方法是一种不需要对对象进行调用的方法,在这里,它的内部机制可以实例化一个对象并将其返回以供将来使用,在这个方法中,有一个对"new"的调用,但在返回之前,可以对该对象进行配置或从缓存中检索。这是这种电话
1 | Logger logger = Logger.getLogger("com.foo"); |
实际的构造函数调用(使用new)是创建新对象的正常方法。