Sunday, April 17, 2011

Classes and Interfaces - Part 2

Design and document for inheritance
  1. Any class should document its public/protected/constructor methods indicating which overridable method it invokes and in what order and how each invocation affects the subsequent processing. Documenting the inner details is unavoidable if you expect a class to be inherited, as otherwise the inherited class might break the assumptions made by the base class.
  2. A class may have to provide hooks into its internal working in the form of judicially chosen protected methods, or in rare instances protected fields.
  3. While using inheritance, constructor should not use overridable methods directly or indirectly particularly in case the overridden method relies on the initialization of some subclass variables.
  4. Classes designed for inheritance should avoid implementing Cloneable and Serializable interfaces as it adds to the burden of those who subclass it. Also, as clone() and readObject() methods behave like constructor, they should also not use any overridable method directly or indirectly.
  5. If you implement Serializable in a possible base class, you should make readResolve and writeReplace methods protected rather than private as otherwise they will be ignored by the subclasses.
  6. If a class is not designed for subclassing, it is always best to prohibit it from being subclassed by either making the constructor private or declaring the class as final.
Prefer inheritance to abstract classes
  1. Existing classes can’t inherit abstract classes. Interfaces are ideal for defining mixins (mixin is a type that a class can implement in addition to its primary type to provide some optional behaviour). Interfaces can extend multiple interfaces. Interfaces enhance safe and powerful functionality enhancement via wrapper classes.
  2. You can provide an Abstract implementation of the Interface always so that the clients can choose to go with any one of them. An existing class can make use of both the Abstract implementation and interfaces as follows. Make the existing class implement the interface. Create a private inner class for the existing class which extends the abstract class. Let all the calls of the existing class forward the request to the inner class. This method is called simulated multiple-inheritance. A variation of this is simple implementation where you provide a concrete class rather than an abstract implementation and the client can override the needed methods. The basis is that it is far easier to evolve an abstract class than an interface.
Use interfaces only to define types
  1. The constant interface pattern (where an interface is used only to expose static final fields) is a poor use of interfaces. To export constants, always go for enums or non-instantiable utility classes. Note: You can always use static import facility to avoid qualifying a constant name with its class name.
Prefer class hierarchies to tagged classes
  1. Tagged classes are those which try to handle multiple cases in a single class. For example, consider a class called Shape which provides area, circumference etc for both circle and rectangle shapes by using a lot of if-else logics. If you want to add a new shape, the class will become messy.
Use function objects to represent strategies
  1. Strategies are usually stateless and hence can also be singletons.
Favour static member classes over nonstatic
  1. There are 4 kinds of nested classes: static member classes, nonstatic member classes, anonymous classes, and local classes.
  2. Static member classes have access to all the private members of the enclosing classes. These classes are like any other static member of the class. If it is declared private, it is accessible only within the enclosing class. Public static classes can be used as a public helper function useful only in conjunction with the enclosing class.
  3. Each instance of a non-static member class is implicitly associated with an instance of the enclosing class (accessed using this instance). It is impossible to create an instance of a non-static member class without an instance of the enclosing class. Common use of such classes is to implement adaptor classes. E.g. you can use non-static member classes to define iterators. These classes are commonly used to represent components of the object represented by its enclosing class.
  4. Anonymous classes have no names and can be declared anywhere an expression is allowed. They are simultaneously declared and instantiated at the point of use. They have enclosing instances if and only if they occur in a non-static context. They are mainly used to create function objects on the fly. E.g. When trying to sort an array, you can pass an anonymous class using an anonymous Comparable interface. They can also be used to create Process objects such as Runnable, Thread, Timertask etc. Static factory methods can use Anonymous classes to provide a different type of implementation of the interface.
  5. Local classes are least frequently used and can be declared anywhere a local variable can be declared. They can’t contain static members.
I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.

Classes and Interfaces - Part 1

Minimize the accessibility of classes and members
  1. Information hiding (a.k.a. encapsulation) is very important to have a very neat API and to have loosely coupled components.
  2. It is advisable to make a class or member as inaccessible as possible. Top-level classes can be package-private or public. If it is being used by only one other class, make it an inner class.
  3. Member variables/methods of a class can be private, protected, package-private, or public.
  4. Java doesn’t allow overridden methods to have a lower scope than the super class. Also all the methods declared in an interface are assumed to be public only.
  5. Classes with public mutable fields are not thread-safe. In general fields of a class must never be public. A final field with reference to a mutable object has all limitations of a non-final field. Note that a non-zero length array is always mutable. So it should never be made public or its reference should never be returned. To fix this problem use Collections.unmodifiableList(Array), or you can clone the array and then return it.
In public classes, use accessor methods, not public fields
  1. If a class is accessible outside its package, provide public accessor methods. In case it is an immutable field, it can be exposed.
  2. If a class is package-private or a private nested class, though it is highly recommended, you can choose to do otherwise also.
Minimize Mutability
  1. Immutable classes are easier to design, test and are less prone to errors. To make a class immutable, don’t provide any method that modifies the objects internal state. Ensure that the class can’t be extended. Make all the fields of the class private and final. If the class contains references to mutable objects, ensure that the clients can never obtain a reference to those objects.
  2. Immutable classes should always take functional approach by creating a new object and returning it rather than modifying the existing object itself.       Immutable classes are always thread-safe. It should also try reusing the same instances rather than creating new ones. Immutable classes should not have any copy constructor.
  3. Immutable classes can also share their internal referenced objects across objects. E.g. BigInteger internally has an int to represent the sign, and an array to store the number. When you use negate() function, it creates a new BigInteger with a different sign, but will reuse the same array of the caller object for optimization reasons.
  4. One disadvantage of immutable classes is that, it might become a performance overhead as new objects have to be created for every minor change in value of the object. If an operation is performed in multiple steps, it might lead to creation of many immutable objects being created.
  5. Generally immutable classes expose a public mutable companion class to perform multistep operations. E.g. StringBuilder is the mutable companion of String class.
  6. If an immutable class implements Serializable interface and it contains fields referring to mutable objects, you must provide an explicit readObject or readResolve method, or use the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnshared methods, even if the default serialized form is acceptable.
Favour composition over inheritance
  1. Unlike method invocation, inheritance violates encapsulation. Subclasses depend on the implementation of super class for proper functioning. Changes in superclass might break the subclasses.
  2. Create a class called Forwarding class in which each method of the composition object has a corresponding method in the Forwarding class. So it is always better for the Forwarding class to implement the interfaces that the contained class has implemented. It becomes more like Decorator. For any value addition, instead of using inheritance, implement a Forwarding class and add the new value to that class.
  3. Disadvantage: Wrapper classes are not suitable for callbacks where an object passes itself to other objects for subsequent invocations. Because a wrapped object doesn’t know of its wrapper, it passes a reference to itself and callbacks elude the wrapper. This is called a SELF problem.
I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.

Friday, April 15, 2011

Methods common to all objects - Part 2


Override clone judiciouslyA class that implements cloneable interface is expected to provide a fully functioning clone method and make the clone method public (Object class provide only a protected implementation of clone method). Clone creates an object without invoking the constructor.
1.      If you override clone method in a non-final class, you should return an object obtained by invoking super.clone. So internally if all classes do it, Object’s clone method will be called creating the instance of the right class.
2.      It is legal for an overriding method’s return type to be a subclass of the overridden method’s return type. This allows the overriding method to provide more information about the returned object and eliminates the need of casting in the client.
3.      Clone method functions as another constructor. You must ensure that it doesn’t harm original object and that it properly establishes invariants on the clone. Clone method should always do a deep-copy wherever it makes sense. E.g. in case of a stack, clone method will copy only the size variable but not the actual elements (it will reference the same object. So you need to clone the array/list also.)
4.      Providing clone methods will become difficult when there are final modifier variables in a class. This is because, after cloning you might want to make the variable reference a new value (or at least the cloned value) which might not be possible.
5.      Clone method should internally use only private methods and final methods.
6.      It is always preferable to use copy constructor or static factory than fixing the complexity of clone method.

Consider implementing Comparable
Comparable interface provides a natural ordering of the objects of a class. Equals() tells whether two objects are equal or not, whereas comparable tells the ordering of the two objects.
  1. By implementing Comparable interface, you can make use of a lot of existing generic algorithms and collection implementation that depend on this interface.
  2. CompareTo method can return a negative value, zero, or positive value as this object is less than, or equal, or greater than the specified object.
  3. You should make sure that sign of x.compareTo(y) = opposite sign of y.compareTo(x). Symmetry, Reflexivity, andTranslative relationship should also hold.
  4. Similar to equals(), there is no way that you can add a value component by subclassing.
  5. Unlike equals(), the parameter of the compareTo is not an Object, but the instance of the specific class itself.
I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.

Methods common to all objects - Part 1


All the non-final methods of the Object class have explicit general contracts and any overrides of these methods should adhere to those contracts failure of which might result in abnormal behaviour.

Obey the general contracts when overriding equals()
  1. In general, an object is always one and only equal to itself as per the default implementation.
  2. Equals are overriden when there is a logical equality between 2 instances. This is more appropriate in case of Value classes.
  3. Instance controlled classes might reuse the equivalent objects efficiently by not allowing 2 objects with equivalent values to get created. In such cases equals() need not be overriden.
  4. The equals method should be reflexive, transitive, symmetric, consistent, and if x is not null then x.equals(null) should always be false.
  5. There is no way to extend an instantiable class and add a value component while preserving the equals contract. The workaround is to use composition rather than inheritence and then add the value component. Remember that such problem wont exist in case of abstract parent classes as you cant create instances of them leading to such different equals() method being called.
  6. Using getClass() method in the equals and comparing only when the current object's class is equal to the other object violates Liskov substitution principle.
Liskov substitution principle: Any important property of a type should also hold for its subtypes, so that any method written for the type should work equally well for its subtype.
It is very easy to break symmetry and transitivity. This is because when you compare a super class object with a subclass object, the subclass might have overriden the implementation of equals method. It might lead to breakage of symmetry behaviour.
SuperClassObject.equals(subClassObject);
A good template of equals() is as follows:
boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof Klass)) return false;
    Klass obj = (Klass) o;
    return obj.a == this.a;
}
While comparing, for non-float fields use ==, for references use equals(), and for float and double use Float.compare and Double.compare.

Always override hashCode when you override equals
As per the Object contract for hashCode, hashCode should always return the same code provided none of the fields used in the equals() comparison has changed. Two objects which return true for equals() should always have the same hashCode. If two objects are not equal, then as far as possible they should not have the same hashCode which might result in increased performance of the hash tables.
  1. You should ALWAYS exclude fields that are not used in equals() while computing the hashCode.
  2. If computing the hashcode is costly for a immutable object, you can consider caching the hashCode for furture references.
Always override toString
As per the Object contract, toString is expected to provide a concise but informative representation that is easy for a person to read. Also it is recommended that all classes override this method.
  1. toString method should return details on all interesting information contained in the object.
  2. Whether or not you decide to specify the format of the toString, you should clearly document your intentions. The disadvantage of specifying the format is that, client may write code which is tightly bound to the format and so changing the format at the later stage becomes difficult.
  3. Also note that, provide accessors to ALL the parameters that you show in the toString. This will help the clients not to rely on just the toString method to get the detail.
I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.

Tuesday, April 12, 2011

Slab allocator


Situation:
Traditional memory allocators have always seen memory as a sequence of bytes available for use. From the layers point of view, memory allocators are below the 'Object' layer and so they have no idea on what kind of object is going to use the memory. In a way it is good, as the implementation of memory allocator becomes simpler. However, it also has a drawback. There are some object whose basic structure doesn't get changed in the course of the execution and so can be reused instead of them going through creation/destruction cycle repeatedly. Also, when the object's initialization becomes very costly, they should be reused as far as possible.

Object caching:
It makes sense for a memory allocator to understand the concept of objects so that memory can be allocated in a better way. So let us introduce a new layer above the usual memory allocator layer which is an object cache. Each type of object has its own cache. When the client requests a cache to allocate an object, the cache checks whether there are any free objects and if there are none, it asks the VM to allocate memory and creates an object and returns it. From the next time on, when the same object becomes free (i.e. when the client releases the object), object creation/initialization part is avoided and the same object is reused from the cache. If the memory manager asks the cache to free up some memory so that it can be reused by other systems, deallocate some objects and return some memory to it. On a cautious note, the object cache layer shouldn't waste memory and should return any unwanted memory to the underlying memory manager when memory manager asks for it.

Client and the central allocator:
Let us call the object caching pool the central allocator. We can split the system up into a client layer which should understand the object completely (including its name, size, how it should be constructed and destructed, its alignment etc) and requests the cache to create an object. The central allocator should take care of the underlying memory management and object caching thereby simplifying the interface for the clients.

Slab allocator:
The central allocator grows or shrinks by 1 slab size. A slab can be visualized as a contiguous memory split into equal-size chunks with a reference count on how many of those chunks are in use right now. To allocate/free a memory, just update the reference count, and return memory from the slab that has extra space. If the reference count goes to zero, the cache can shrink itself by the size of one slab. Slab allocator also reduces internal and external fragmentation issues as it already knows the size of the object it is always going to allocate.

Architecture:
A cache is always going to have similar objects only. It grows or shrinks by the size of a slab. So the cache maintains a circular doubly linked list to go to all slabs it manages right now (the node is called kmem_slab also has a reference count so that it can be deallocated later). Internally a slab is a contiguous memory whose size might span across pages. To know which objects are free to use right now, each slab maintains an additional free-list (the node is called kmem_bufctl which has the buffer address and a back pointer to the kmem_slab node). When the object size becomes very small, maintaining a free-list becomes an overhead as it occupies a lot of memory. So the kmem_slab and kmem_bufctl are all maintained at the end of the slab memory itself. Also kmem_bufctl wont be a linked list anymore but just bit vector showing whether an object in slab is in use or not.

Working of a Slab allocator:
The slabs are arranged in a particular order based on its usage; i.e. all free slabs are maintained at the end of the cache's DLL before which comes the partially used slab. The cache internally has a free-list pointer pointing to the first non-empty slab from which it can start allocating objects whenever a client places a request (remember, it also updates the reference count of the slab). The non-empty slab will then return the object from its buffer.
When an object is being returned by the client, if the reference count of the corresponding slab becomes zero, it is appended to the tail of the cache's free list. When the system runs low on memory, it will demand the slab allocator to release some memory. The slab allocator in turn releases some of its free slabs which have not been used recently. It doesn't release all free lists to avoid thrashing.

Usage:
Slab allocator are being used by many operating systems including Linux and Solaris, as it has been proven to work very efficiently. Memcached also uses this to avoid internal fragmentation.

Sunday, April 10, 2011

Creating and Destroying Objects - Part 2


Avoid creating unnecessary objects
1.      You can sometimes avoid creating unnecessary objects by using static factory methods.
2.      Objects should be reused when they are immutable.
3.      Lazy initializations are NOT preferrable as it might complicate simple code unnecessarily.
4.      Any stateless object need not be created multiple times. E.g. Adaptor classes are generally stateless and can be reused.
5.      Java has a lot of classes equivalent to its primitives. E.g. Long class is similar to long primitive. As far as possible, try using primitives. Prefer using primitives to boxed primitives and watch out for unintentional autoboxing (conversion from primitive to boxed primitive).

Eliminate obsolete object references
1.      Obsolete references are those references which wont be deferenced again. Such unintentional object references might miss garbage collection.
2.      Make all the object references null once they become obsolete.
Places to watch out for memory leaks:
1.      Whenever a class matches its own memory. E.g. Stacks.
2.      Caches – nullify all the cached items once they become outdated. Make use of WeakHashMap which are designed to do exactly this. They will get cleared automatically when all the outside references have become null. Other classes which do the same are LinkedHashMap. Java.lang.ref provides more sophisticated caches.
3.      Listeners and other callbacks – Listeners might register callbacks but may not deregister. The best way to ensure that callbacks are garbage collected is to store only week references.

Avoid Finalizers
1.      Finalizers are unpredictable, often dangerous, and generally unnecessary and can lead to severe performance penality, erratic behaviour, and introduce issues in portability.
2.      JVM doesn't provide any guarantee about when it will execute finalizers. In fact it doesnt guarantee its execution at all. So any critical code like freeing an expensive resource should never be done on finalizers.
3.      System.gc and System.runFinalization might increase the probability of finalizer running, but it doesnt guarantee anything. System.runFinalizersOnExit guarantees the execution of finalizer but might be deprecated soon.
4.      When you want to free a resource, provide an explicit terminate() method which the client can use to free the resource. In case the client doesnt call it, then fall back on finalizers.
5.      Also call the terminate() method in the finally block, so that it is almost always guaranteed to work.
6.      Finalizer chaining (calling the superclass's finalizer method) is not done automatically. So when you override a superclass implementation of finalizer method, you should explicitly call the finalizer of the superclass.
When to use finalizers
1.      Finalizer can work as a fallback, but even in that case it is good to log an error as the resource hasnt terminated properly and the code bug needs to be fixed.
2.      While dealing with native objects, you can use finalizers to release some critical resources. This is because JVM doesn't keep track of native objects and so they wont be garbage collected.

I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.

Creating and Destroying Objects - Part 1


Consider static factory methods instead of constructors
Advantages:
1.      You can choose a meaningful name for the factory method which is not possible with constructors.
2.      Static factory methods can choose when to create an object. They can reuse the existing object instead of creating a new one by caching the instances as and when being constructed (Classes doing this are called instance-controlled).
3.      Based on the arguments, the static method factory can decide to return a different sub-type of the promised return type which need not be even public.
4.      They reduce verbosity of creating parameterized types (Shown below).
Disadvantages:
1.      If you provide only static factory method and make constructors private, you can't subclass it.
2.      The API documentation will have a list of static factory methods along with other static methods, and there is no clear way to differentiate them.
Conventions:
1.      Static factory methods are sometimes provided in a dedicated class. If the type they are going to return is called Type (E.g. Car), the class containing the static factory methods is called Types (E.g. Cars).
2.      Static factory methods usually have the following names. ValueOf, getInstance, newInstance, getType, newType.
Code where verbosity is reduced:
Map<String, List<String>> m =  new HashMap<String, List<String>>();

Can be expressed as:
public static <K, V> HashMap<K, V> newInstance() {
    return new HashMap<K, V>();
}
Map<String, List<String>> m = HashMap.newInstance();


Consider a builder when faced with many constructor parameters.
1.      Telescoping constructors (providing multiple constructors) wont scale when there are too many parameters to be added. And it will make the life of client very complicated.
2.      JavaBeans pattern (providing setters for all the fields) might leave object in an inconsistent state when client doesnt set all values well. You may want to freeze the object till it is being built correctly and then unfreeze it. However this solution is not being used in general.
3.      Using Builder Pattern is a better choise as it simulates a named optional parameter and the build() method can ensure that all required values are set properly.
4.      Disadvantage of using builder is that the client side code becomes more verbose.

Enforce singleton property with a private constructor or an enum type.

Enforce noninstantiability with a private constructor
1.      There are cases where you want a class not to have any instance. The class might just be a grouping of a collection of static utility methods, or static factory methods.
2.      You can make the class abstract and thereby prevent direct instance being created for that class. However this can be broken easily by extending the abstract class and creating objects of the inherited class.
3.      Make the constructor private and then throw an exception from within so that no one can create (even from inside the class) an instance of this class.
As a side effect, making the constructor private prevents the class from being extended.

I have taken these points from the book "Effective Java" which I consider as a MUST READ book for every JAVA developer.