Why use Lazy Instantiation when static initialization is more efficient? Well, there are pros and cons to both, and there is no firm answer.
The Singleton article gave one solution for implementing global variables, but it wasn't the only solution. Java does, in fact, have global variables of a sort, but they're called class variables. Here is an example:
"The most important reason for using Lazy Instantiation is keeping resources under control. "
static MyObject object1 = new MyObject()
In Listing 1, the static keyword is used to indicate that this particular variable, namely object1, is a class variable rather than an instance variable. This means that there will be only one copy of the variable for the class rather than one for each instance of the class. The code segment in Listing 1 not only creates the variable, it also contains a static initializer that gives the object a value. This static initialization occurs automatically when the class containing the variable is first accessed.
Here, first accessed is defined to be the first time one of the following events occurs:
An instance of the class is created via a constructor.
A static method that is defined in the class (not inherited) is called.
A static variable that is declared in the class (not inherited) is assigned or otherwise accessed. This does not include the static initializer, which occurs at compile time.
The process of Lazy Instantiation, on the other hand, doesn't automatically allocate variables. It enables the creation of objects to be put off until they are actually needed. Instead of being created when the program first starts, the creation of variables managed via Lazy Instantiation is deferred until they are actually required.
Which is better? Lets start off with some examples.
Here is an example of static initialization:
public class MyClass {
static MyObject object1 = new MyObject();
void doProcess() {
object1.process();
}
}
In Listing 2,object1 is created and its value is initialized when the class
MyClass is first accessed. After some period of time,object1 will be used via the
doProcess() method.
Here is a similar code segment making use of Lazy Instantiation.
public class MyClass {
MyObject object1;
void doProcess() {
If (object1 == null)
object1 = new MyObject();
object1.process();
}
}
The code in Listing 3 performs the same function as in Listing 2 except that the
object1 variable is being managed via Lazy Instantiation. When MyClass is created, nothing is done with object1 other than implicitly setting its reference to null. The doProcess() method makes use of object1 and checks to see if it exists before using it. If it does not exist, an instance is created and then used.
Now back to the big question: Which is better?
Different Purposes
When it comes to speed, the static version wins. Static methods are quicker than normal ones, as there is no code execution overhead. Classes implementing Lazy Instantiation contain management code that needs to be executed whenever access to a variable is required. In Listing 3, overhead is incurred every time object 1 is accessed, because it first needs to be checked for a null value.
For ease of programming, static wins again. Only a single line of code is required to implement a variable with a static initializer. As mentioned above, Lazy Instantiation requires that an object be checked for a null value every time it is accessed. Also, multithreaded applications would require use of the double-checked locking pattern, which results in additional code. (See previous article on Singletons for more information on this.)
Okay, so there are several reasons for using a static initializer, as my readers have mentioned. However, there are several good reasons to use Lazy Instantiation instead.
The first reason for Lazy Instantiation concerns the initialization of the managed object's value. For a static initializer, the initial value is determined at compile time. When the developer puts to code the line that creates the object, he or she also determines what the initial value is going to be. While this is fine for many uses, there are times when it just isn't good enough. Lazy Instantiation, however, initializes the value of an object when the object is created. Since the object is being created at runtime, there is much more data available which can be used to calculate an appropriate initial value. One example of this would be the placing of a user name and id in a session variable.
Secondly, items that are static cannot be used to implement an interface. Interfaces in Java are powerful programming constructs that allow classes to inherit method definitions. Static objects suffer a loss of a great deal of programming power by not being able to implement interfaces.
The most important reason of all for using Lazy Instantiation, however, is that of keeping resources under control. Static objects are always created, whether they are needed or not. If the object is never used, then space is wasted holding the object and time is wasted creating it. Objects managed by Lazy Instantiation will only be created if they are needed and do not suffer these problems. This is especially important if the resources used are valuable, such as a database connection. Why tie up a database connection if it is never going to be used?
Also, since static objects are created during the initialization of a Java program, a lot of processing needs to be done before the program can actually begin. Software built with Lazy Instantiation defers the creation of objects and thus starts up a lot faster. This makes the Java program appear more agile and responsive, a definite bonus if you are trying to sell the software to a client.
Summary
The pros and cons of static initializers versus Lazy Instantiation must be weighed to determine which is best for a given use. Both are powerful, and both are examples of good programming, but they serve different purposes.
分享到:
相关推荐
PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more....
此加载项对app/initializers和app/instance-initializers内部的文件进行迭代,并通过传递文件的解析名称来分别调用app.initializer和app.instanceInitializer方法。安装ember install ember-load-initializers贡献...
Kubernetes Initializers工作原理介绍.pptx
1.6.6.3 Static and instance methods 17 1.6.6.4 Virtual, override, and abstract methods 18 1.6.6.5 Method overloading 20 1.6.7 Other function members 21 1.6.7.1 Constructors 22 1.6.7.2 Properties 23 ...
eclipse 的code style 下的cleanup 格式化模板 ...Sort members excluding fields, enum constants, and initializers Organize imports Format source code Correct indentation Remove redundant type arguments
)用法将js-initializers添加到您的 Gemfile # Gemfilegem 'js-initializers' 将js-initializers添加到您的链轮清单: //= require js-initializers 等等! 您已准备好添加初始化程序: // app/assets/javascripts/...
Scoping Namespaces Nested Classes Nonmember, Static Member, and Global Functions Local Variables Static and Global Variables Classes Doing Work in Constructors Default Constructors Explicit ...
Instance and Static Members 193 Fields 194 Methods 195 Properties 196 Indexers 198 Reviewing Where Partial Types Fit In 199 Static Classes 200 The System.Object Class 201 Summary 204...
Integrated coverage of new C# 6 functionality: string interpolation, expression-bodied methods and properties, auto-implemented property initializers, getter-only properties, nameof, null-conditional ...
LINQ, Object/Collection Initializers OOP: Classes, Objects, Inheritance, Polymorphism, Interfaces WinForms, WPF, XAML, Event Handling WPF GUI/Graphics/Multimedia Silverlight® Lists, Queues, ...
LINQ, Object/Collection Initializers OOP: Classes, Objects, Inheritance, Polymorphism, Interfaces WinForms, WPF, XAML, Event Handling WPF GUI/Graphics/Multimedia Silverlight® Lists, Queues, ...
Item 12: Prefer Member Initializers to Assignment Statements 74 Item 13: Use Proper Initialization for Static Class Members 77 Item 14: Minimize Duplicate Initialization Logic 79 Item 15: Utilize ...
Most notably, of course, it has been updated to cover all the new features of C# 3.0, including object and collection initializers, anonymous types, lambda expressions, query expressions, and partial...
资源来自pypi官网。 资源全名:dodoo-initializer-0.5.1.tar.gz
C语言编程中常见的错误汇总,可以帮助C语言学习和使用者排除各种C语言编程中遇到的错误
6.1.8 Measurement with time can have Errors and Variations . 68 6.1.9 Select a Test Case that Exposes the Runtime Bottleneck . . 68 6.1.10 The Difference Between Algorithm and Implementation . . 70 ...
Initializers 437 Type Inference 443 Anonymous Types 445 Extension Methods 449 Lambda Expressions 455 Summary 466 Exercises 467 Part II: Windows Programming 468 Chapter 15: ...
JavaScript权威指南(第6 Preface . . . . . . . ....1. Introduction to JavaScript ....Part I....2. Lexical Structure ....4.2 Object and Array Initializers 58 4.3 Function Definition Expressions 59 vii版
Object and collection Initializers 235 Anonymous Type .237 The System. Tuple type 240 Parameterful Properties 242 The performance of calling property accessor Methods 247 Property Accessor ...