Creating and destroying objects

2,029 views

Published on

This is a presentation from Effective Java, Chapter 2 : Creating and Destroying Objects.

This presentaiton was created by Nishant Puri.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,029
On SlideShare
0
From Embeds
0
Number of Embeds
161
Actions
Shares
0
Downloads
35
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Creating and destroying objects

  1. 1. ITEM 1<br />Consider static factory methods instead of constructors <br />
  2. 2. Is simply a static method that returns an instance of the class<br /> ADVANTAGES<br />They have names. <br />They are not required to create a new object each time they are invoked.<br />They can return an object of any subtype of their return type.<br />Best example for this is : Collection API<br />They reduce verbosity of creating parameterized type instances.<br /> DISADVANTAGES<br />When providing only static factory methods, classes without public or protected constructors cannot be subclassed.<br />They are not readily distinguishable from other static methods<br />static factory methods <br />
  3. 3. Example<br />Car Factory produces different Car objects<br />Ordinary<br />Different classes implement Car interface<br />Directly instantiate car objects<br />Need to modify client to change cars<br />Using pattern<br />Use carFactory class to produce car objects<br />Can change cars by changing carFactory<br />Factory Pattern<br />
  4. 4. class 350Z implements Car; // fast car<br />class Ram implements Car; // truck<br />class Accord implements Car; // family car<br />Car fast = new 350Z(); // returns fast car<br />public class carFactory {<br /> public static Car create(String type) {<br /> if (type.equals("fast")) return new 350Z();<br /> if (type.equals("truck")) return new Ram();<br /> else if (type.equals(“family”) return new Accord();<br /> }<br />}<br />Car fast = carFactory.create("fast"); // returns fast car<br />Factory Example<br />
  5. 5. By default, constructors should be preferred, because they are simpler to understand and write. <br />However, if you specifically need to decouple the construction niceties of an object from its semantic meaning as understood by the client code, you'd be better off using factories.<br />Constructors<br />
  6. 6. Use static factory methods for a more intuitive API, to improve performance via object-caching, to implement singletons, in interface-based frameworks, and to return objects of private classes. <br />Use constructors in classes designed for inheritance (there shouldn’t be many of these) and for greater visibility in API documentation (since they appear in a separate table in standard Javadocs).<br />The verdict?<br />
  7. 7. Item 2<br />Consider a builder when faced with many constructor parameters<br />
  8. 8. Telescoping Constructor Pattern<br />JavaBeans Pattern<br />Builder Pattern<br />
  9. 9. This method is the traditional way of dealing with the problem of many constructor parameters.<br /> The problem being that but it is hard to write client code when there are many parameters, and harder still to read it.<br />Telescoping Constructor Pattern<br />
  10. 10. The approach is that we call the parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest.<br />Limitations<br />Because construction is split across multiple calls a JavaBean may be in an inconsistent state partway through its construction.<br />This pattern precludes the possibility of making a class immutable<br />JavaBeans Pattern<br />
  11. 11. The third alternative that combines the safety of the telescoping constructor pattern with the readability of the JavaBeans pattern is the builder pattern.<br />Instead of making the desired object directly, the client calls a constructor (or static factory) with all of the required parameters and gets a builder object. Then the client calls setter-like methods on the builder object to set each optional parameter of interest.<br />Builder Battern<br />
  12. 12. public Builder calories(intval) { calories = val; return this; <br /> }<br /> public Builder fat(intval) { <br /> fat = val; return this; <br /> }<br /> public Builder carbohydrate(intval) { <br /> carbohydrate = val; <br /> return this; <br /> }<br /> public Builder sodium(intval) { sodium = val; return this; <br /> }<br /> public NutritionFacts build() {<br /> return new NutritionFacts(this);<br /> }<br />}<br />private NutritionFacts(Builder builder) {<br />servingSize = builder.servingSize;<br /> servings = builder.servings;<br /> calories = builder.calories;<br /> fat = builder.fat;<br /> sodium = builder.sodium;<br /> carbohydrate = builder.carbohydrate;<br />}<br />} <br />NutritionFactscocaCola = new NutritionFacts.Builder(240, 8).<br />calories(100).sodium(35).carbohydrate(27).build();<br />// Builder Pattern<br />public class NutritionFacts {<br /> private final intservingSize;<br /> private final int servings;<br /> private final int calories;<br /> private final int fat;<br /> private final int sodium;<br /> private final int carbohydrate;<br /> public static class Builder {<br /> // Required parameters<br /> private final intservingSize;<br /> private final int servings;<br /> // Optional parameters-initialized to //default values<br /> private int calories = 0;<br /> private int fat = 0;<br /> private int carbohydrate = 0;<br /> private int sodium = 0;<br /> public Builder(intservingSize, int servings) {<br />this.servingSize = servingSize;<br />this.servings = servings;<br /> }<br />
  13. 13. Advantages<br />It is flexible in the sense that a single builder can be used to build multiple objects. <br />The parameters of the builder can be tweaked between object creations to vary the objects.<br />Disadvantages<br />In order to create an object, you must first create its builder which could be a problem in some performance critical situations. <br />Also, the Builder pattern is more verbose than the telescoping constructor pattern, so it should be used only if there are enough parameters, say four or more<br />
  14. 14. The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if most of those parameters are optional. <br />Client code is much easier to read and write with builders than with the traditional telescoping constructor pattern.<br />Builders are much safer than JavaBeans.<br />To Summarize<br />
  15. 15. Item 3<br />Enforce the singleton property with a private<br />constructor or an enum type<br />
  16. 16. A singleton is simply a class that is instantiated exactly once<br />Often in designing a system, we want to control how an object is used, and prevent others (ourselves included) from making copies of it or creating new instances. <br />Scenario/Use-Case<br />Consider a central configuration object that stores setup information. It should have one and one only instance - a global copy accessible from any part of the application, including any threads that are running. Creating a new configuration object and using it would be fairly useless, as other parts of the application might be looking at the old configuration object, and changes to application settings wouldn't always be acted upon. So this is one of the cases wherein we would need the concept of singleton.<br />singleton<br />
  17. 17. Prior to 1.5<br />public class SingletonObject { <br /> private static SingletonObject ref; <br />privateSingletonObject() { <br /> // no code required <br /> } <br /> public static SingletonObjectgetSingletonObject() { <br /> if (ref == null) <br /> ref = new SingletonObject(); <br /> return ref; <br /> } <br />}<br />Approaches for singleton<br />
  18. 18. Preventing thread problems with your singleton<br />public static synchronized SingletonObjectgetSingletonObject()<br />This is important because this would prevent two threads from calling the getSingletonObject() method at the same time. If one thread entered the method just after the other, you could end up calling the SingletonObject constructor twice and returning different values.<br />Another possible way to violate the design principles of the singleton is with the help of the clone() method which would create and return a copy of the singleton object.  So, to avoid this, we must add a clone() method of our own, and throw a CloneNotSupportedException.<br />
  19. 19. How does serialization affects singleton??<br />it is not sufficient merely to add implements Serializable to its declaration. To maintain the singleton guarantee, you have to declare all instance fields transient and provide a readResolve() method. Otherwise, each time a serialized instance is deserialized, a new instance will be created.<br />
  20. 20. For example:<br />// readResolve for instance control -<br />private Object readResolve() {<br /> // Return the one true Elvis and let the garbage collector take //care of the Elvis impersonator.<br />return ref;<br /> }<br />This method ignores the deserialized object, returning the distinguished instance that was created when the class was initialized<br />
  21. 21. As of release 1.5<br />// Enum singleton - the preferred approach<br />public enum Elvis {<br /> INSTANCE;<br /> public void leaveTheBuilding() { ... }<br /> }<br />This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.<br />
  22. 22. Item 4<br />Enforce non-instantiability with a private constructor<br />
  23. 23. Use case/ scenario<br />Creating a utility class which is just a collection of static maethods<br />Such utility classes are not designed to be instantiated because the class is just a grouping of static methods and static fields so an instance would be nonsensical.<br />
  24. 24. public class UtilityClass{<br />//Suppress default constructor for noninstantiability<br />private UtilityClass() {<br /> throw new AssertionError();<br /> }<br /> }<br />The AssertionError provides insurance in case the constructor is accidentally invoked from within the class.<br />Noninstantiable utility class<br />
  25. 25. Item 5<br />Avoid creating unnecessary objects<br />
  26. 26. It is often appropriate to reuse a single object instead of creating a new functionally equivalent object each time it is needed. Reuse enhances performane as it is faster.<br />String s = new String(“nishant");//never do!<br />String s = “nishant";<br />This was the case of immutable objects but even for mutable objects you should reuse them if you know they won’t be modified.<br /><ul><li>Example :</li></li></ul><li>There’s a new way to create unnecessary objects in release 1.5. It is called autoboxing.<br />Example<br />public static void main(String[] args) {<br /> Long sum = 0L;<br /> for (long i = 0; i < Integer.MAX_VALUE; i++) {<br /> sum += i;<br /> }<br />System.out.println(sum);<br /> }<br />The variable sum is declared as a Long instead of a long, which means that the program constructs about 231 unnecessary Long instances.<br />The lesson is clear: prefer primitives to boxed primitives, and watch out for unintentional autoboxing.<br />
  27. 27. Item 6<br />Eliminate obsolete object references<br />
  28. 28. An obsolete reference is simply a reference that will never be dereferenced again.<br />This can be explained with the help of the following example….<br />Stack example<br />What is an obsolete reference ?<br />
  29. 29. Whenever a class manages its own memory, the programmer should be alert for memory leaks.<br />Simply put, it manages its own memory.<br />The elements in the active portion of the array are allocated, and those in the remainder of the array are free. <br />The garbage collector has no way of knowing this<br />For the GC all of the object references in the elements array are equally valid. <br />Only the programmer knows that the inactive portion of the array is unimportant. <br />The programmer effectively communicates this fact to the garbage collector by manually nulling out array elements as soon as they become part of the inactive portion.<br />So where is the problem ?<br />
  30. 30. Whenever an element is freed, any object references contained in the element should be nulled out.<br />Another common source of memory leaks is caches<br />When should you null out a reference ?<br />
  31. 31. Item 7<br />Avoid finalizers<br />
  32. 32. In C++, destructors are the normal way to reclaim the resources associated with an object, a necessary counterpart to constructors. <br />In Java, the garbage collector reclaims the storage associated with an object when it becomes unreachable, requiring no special effort on the part of the programmer. <br />C++ destructors are also used to reclaim other nonmemory resources. <br />In Java, the try finally block is generally used for this purpose.<br />
  33. 33. There is no guarantee they’ll be executed promptly so never do anything time-critical in a finalizer.<br />The promptness with which finalizers are executed is primarily a function of the garbage collection algorithm, which varies widely from JVM to JVM<br />It is entirely possible, even likely, that a program terminates without executing finalizers on some objects that are no longer reachable. As a consequence, you should never depend on a finalizer to update critical persistent state<br />Limitations<br />
  34. 34. If an uncaught exception is thrown during finalization, the exception is ignored, and finalization of that object terminates. Uncaught exceptions can leave objects in a corrupt state. If another thread attempts to use such a corrupted object, arbitrary nondeterministic behavior may result. Normally, an uncaught exception will terminate the thread and print a stack trace, but not if it occurs in a finalizer.<br />There is a severe performance penalty for using finalizers. On my machine, the time to create and destroy a simple object is about 5.6 ns. Adding a finalizer increases the time to 2,400 ns<br />Contd.<br />
  35. 35. Explicit termination methods are typically used in combination with the try-finally construct to ensure termination<br />Examples: close method, cancel method <br />// try-finally block guarantees execution of termination method<br />Foofoo = new Foo(...);<br /> try {<br /> // Do what must be done with foo<br /> ...<br /> } <br /> finally {<br />foo.terminate(); // Explicit termination //method<br /> }<br />Work-around<br />
  36. 36. They have 2 legitimate uses:<br />One is to act as a “safety net” in case the owner of an object forgets to call its explicit termination method<br />A second legitimate use of finalizers concerns objects with native peers. A native peer is a native object to which a normal object delegates via native methods.<br />Because a native peer is not a normal object, the garbage collector doesn’t know about it and can’t reclaim it when its Java peer is reclaimed. A finalizer is an appropriate vehicle for performing this task, assuming the native peer holds nocritical resources<br />So what are the finalizers good for ?<br />
  37. 37. AWT uses native code (code specific to a single operating system) to display its components. Each implementation of the Jave Runtime Environment (JRE) must provide native implementations of Buttons, Labels, Panels, and all of the other AWT components.<br />Whenever you use an AWT component, if forwards all of its drawing requests to a piece of native code. This allows you to generically use an AWT Button in your application, but the Button appears as a Windows Button, a Motif Button, a Mac Button, or a real button on whatever platform you are running.<br />These pieces of native code are referred to as peers, as they share the responsibility for displaying a component.<br />Peer code includes native code to display components, as well as draw lines, determine platform specifics such as current screen size, and other native platform issues.<br />

×