Translate

Search This Blog

Monday 27 April 2020

About Java 8 Streams


What are Streams in Java?
You probably must have heard about stream before Java 8, in a different context while working with input and output ex. FileInputStream and FileOutputStream allowing us to use the contents in the file as stream of bytes or characters. 

Java 8 Stream works at a different level on a sequence of elements in a data source like Collections or Arrays. Various intermediate operations can then be pipe-lined together on the Stream to transform or filter the elements and finally the results can be collected in a terminal operation.  

Note : Stream maintains the order of the data as it is in the data source.

When was it introduced?
Stream API where introduced as part of Java 8. It provides abstraction on operations that can be performed on sequence of elements. 

How to use Streams?
Stream are available to us on Collections, if you check the Java 8 api for Collection interface, you will find that it has default methods like stream and parallelStream, that gives us the Stream object. 

You would then work with the Stream object using various intermediate operation and terminal operation on them.

Some of the significant intermediate operation available are

  • filter
    • takes a predicate that can be used to filter our elements that match the condition.
  • map
    • takes an function as an argument that helps to get mapped elements out of the stream. 
  • flatMap
    • similar to map it takes function as an argument and after mapping flattens the elements of the result into the output stream. Ex: Stream.of(list,list) could be flattened into a single list for consumption.
  • distinct
    • retrieves distinct values from the stream of elements.
  • sorted
    • sorts the values in the stream.

Some of the significant terminal operations available are
  • reduce
  • count
  • collect
  • forEach
  • match
  • findFirst

Where to use Streams?
Stream classes support functional-style operations on streams of elements, such as map-reduce transformations on collections. The code written is much cleaner and expressive. 

You could achieve performance improvements through the use of parallelStream which help to take advantage of the multi core system.

References:

Thursday 16 April 2020

Why do we need an Immutable key in an HashMap

In my previous posts, I explained the contract of equals and hashCode methods and also explained how the HashMap works in Java. If you have not read it I would suggest you to strongly read it before you read this topic.

To understand this topic we should first know what happens if the key is mutable.

Let's take the put operation for example
Whenever we implement hashCode method, we need to keep in mind that it should not include fields which are mutable.

If it does, then clearly the hashCode implementation will return different value then the previous time it was invoked.  i.e. when the state of the object is modified, then the hashCode will differ.

What happens then, is that during the process of insertion of the key, value pair, the hash value calculated for the key, in order to find the index of the bucket differs from the earlier one (Note: The post on how HashMap works will come in handy here for clear understanding) and the key, value would be place in a different bucket. As a result, the earlier node in the bucket list will be never reached and hence would be dangling forever.

So what happens if the key is modified and we try to retrieve?
Imagine, the key, value pair is already placed in a specific location in the bucket based on the key. Now if the Key is mutated, a new hashCode is formed, it causes indexFor method to return a different index to look for the key and hence won't be found, resulting in null value to be returned.

Hence, it is strongly advised to have they key as immutable so that the HashMap does not loose track of the bucket where they key was placed. This is the case for all Hash based collections.

What are the Interface enhancements in Java 8


Interface enhancements in Java 8

With Java 8, interfaces can now have default method and static method within the interface definition.

Default method, help to add new behaviour in the interface which if otherwise added would break all implementing classes. You can add default method through the use of the keyword default.

For Example,
If you notice the Iterator interface, it has added a new default method named forEachContaining(Consumer c) 

Similarly, Java 8 has modified many of its other interfaces to add new behaviour, but if you realise hasn't broken any functionality in the previous version (i.e. how it has maintained backward compatibility)

Static method, can also be added in the interfaces through the use of keyword static, except that they cant be overridden, exactly for the same reason as to why they weren't possible when associated with classes .

What happens to abstract classes?

Interfaces as earlier, still abstract out behaviour and can relate entities which are unrelated in hierarchy but common in behavioural interfaces.

For example: Sound interface with method makeSound still holds true when modelling Animal hierarchy and Instruments hierarchy.

Where as we would still use abstract classes when we want to abstract out common behaviour when there is strict hierarchy among classes.

What happens when two interfaces have default method with same signature?
Which also brings us to another point, what happens when two interfaces have common default method. Compiler complains saying "inherits unrelated defaults" and forces you to over ride the method.

Java8 - Functions



What are java 8 Functions all about?

  • Functions are a new addition in Java 8.
  • Are used to implement Functional programming in Java
  • Java 8 Function's are Functional interfaces and they have a single abstract method  
    • For example, the Function interface has a single abstract method apply() .
  • There are various flavours of it present in the java.util.function package. 
Why do we need a Function interfaces?
  • Its purpose lies in that, it abstracts out the behaviour of a function. i.e a function takes an input and gives an output.
    • i.e. broadly map object of one type and converts it to another [R apply(T)], 
    • For example, the map function in streams converts/maps object of one type to another.
      • Note: 
        • Not all interfaces in the function package, adhere to this rule. 
          • For example Consumer interface within function package just excepts a value and does not return anything.
How is it used?

  • Functions are functional interface and hence it finds it usages in places where it can be used as Lamda expressions.
What are the various functions present in the functions package?
Following are the main functional interfaces and all others are variations to these interfaces. If you understand these interfaces , you would quickly grasp the rest of the interface functions.

1. Function

  • Represents a function that accepts one argument and produces a result.
  • This interface has the following functions defined
    • R apply(T) - abstract method which takes an argument of type T and returns R
    • andThen(Function after) - its a default method, it combines the Function on which it is applied(T,R)  with another function named after (going from R to V), so that the net affect is a composed function which results in transformation from T to V.
    • compose(Function before) - its again another default method, it first applies the function(V,T) given as parameter and then applies this function(T,R) to give a combined function whose net effect is  a composed function which results in transformation from V to R.
    • identity() - is a static function which always returns a function that always returns its input argument.

2. Consumer
  • Represents an operation that accepts a single input argument and returns no result.
  • This interface has the following methods
    • void accept(T t) - Performs this operation on the given argument.
    • andThen(Consumer after) - Returns a composed Consumer that performs, in sequence, this operation followed by the after operation.
3. Supplier
  • Represents a supplier of results
  • This interface has the following methods.
    • T get() - gets the result.
4. Predicate
  • Represents a predicate (boolean-valued function) of one argument.
  • This interface has the following methods
    • boolean test(T t) - and abstract method that evaluates this predicate on the given argument.
    • and(Predicate other) - default method that returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.
    • or(Predicate other) - default method that returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.
    • isEqual(Object other) - static method that returns a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).


References:

Wednesday 13 June 2018

Java8 - Functional interfaces

Functional interfaces
Java8 has added to it's kitty another concept know as functional interfaces.

So what exactly is an functional interfaces?

  • Functional interfaces are interfaces with exactly a single abstract method (SAM). 
  • It is represented by the annotation type @FunctionalInterface. 
    • This annotation let's the compiler know that the interfaces should adhere to the contract of SAM.

NOTE:

  • A couple of things here that this interface can also have other default functions but not another abstract method. 
  • These interfaces can also be extended by another interfaces and can be called functional interface as long it does not have another abstract method.
  • Also compiler will treat all SAM interfaces as functional regardless if the annotation is present or not.


So how do we use this interfaces?
These interfaces can be represented using

  • Lamda expressions 
  • Method reference and 
  • Constructor reference.(Lamda expressions another important concept I have covered in another blog article)


Examples of functional interfaces
in Java8 are Runnable, Comparator, ActionListener, Callable etc.



Tuesday 5 June 2018

Java8 - Lamda functions

Java8 - Lamda expressions

What are Lamda expressions?
Lamda expressions is Java's introduction to functional programming.  Lamda expressions can be created and passed around like regular objects and executed when needed.

Why do we have Lamda expressions?
Java is often criticised as verbose, with Lamda expressions there is an attempt to decrease this verbosity. They address the bulkiness of the anonymous inner classes.

With lamda expression you can now represent single method interfaces in a simple and concise way. These single method interfaces are often termed as functional interfaces as in Java8. If you do not know about functional interfaces check my other post on the same.

So how do we create these Lamda expression?
Lamda expressions are composed of 3 parts:
1. Argument list
     It is represented like any other method definition like for example () or (int x, int y) etc
2. Arrow token
    Represented by the -> symbol
3. Body
    If the body consists of a single line then curlies are not required.

Example of such an expression is 

Runnable r = () -> System.out.println("I am running"); 

It is worth noting that the expressions find their usage in places where there are interfaces with single abstract method. This way, the compiler knows how to exactly match the argument list and the method to the definition in the interface. 

If you understand this article it will form the basis for the next article where we will dive into the intricacies of lamda expression 

Wednesday 14 September 2011

How does HashMap work in Java

We all know and must have used HashMap, its a Map interface implementation. It stores keys and its corresponding value. Keys cannot contain duplicates and can contain at the most one null key (HashTable does not allow null as key, FYI). It has non synchronized methods unlike HashTable. It does not guarantee the order of retrieval (it changes every time the HashMap is modified) etc etc. Enough of this now..


So how does HashMap work?
Basically when this question is asked it generally means how is the object stored and retrieved from the     HashMap. But of course with the get and put methods in the Map API. Easy isn't it, but that is not what
meets the eye. We need to understand what goes inside to understand the answer to the title of this topic.

So what happens when you put a key/value pair in the HashMap, Firstly, hashCode of the key is retrieved and supplied to hash function to defend against poorly constructed hashCode implementation; to get a new hash value. This value is then used to figure out which bucket the entry (Entry is an static inner class within the HashMap structure, which stores the key, its associated value and the reference to the next entry, it is created whenever you try to put an new mapping in the HashMap; Buckets are nothing but an array of Entry objects) should belong to, using another method named indexFor which calculates the index for the bucket. (Initially, the number of buckets within the HashMap is equal to in the initial capacity of the Map,FYI).
Once the index is found, if there is an entry at that location in the bucket; then that entry's hash value and key is checked for equality with the new key if they are same the old value is replaced, else the old entry is marked as successor to the new entry forming a singly linked list. If there is no entry at the calculated index location; the new value is stored at that location.

What happens when you retrieve the key from the Map using get? If you understand how the above put logic works, retrieval logic is easy. We first, get the hash value by applying the hash function to the hashCode of the key. This value is then used to calculate the index value of the bucket. Using this index we get the entry, if the hash value  and the key of the retrieved entry and key passed is the same then the value is returned, else we traverse the linked list till we get the value. If not we return null.

This above understanding helps us to understand various questions
  • What is HashMap? Why do we use it?
  • How does HashMap work? How does the get method work?
  • What will happen when two different objects has same hashCode, (during both insertion and retrieval)
Another interesting thing to note is what happens when the capacity of the HashMap is reached.  As said in the java docs, when the number of entries exceeds the product of the load factor and the current capacity, the capacity is roughly doubled by calling the rehash method. Note, when rehashing happens, issues like race conditions can occur when the HashMap is used concurrently.
Also, the iterator returned by some of the methods in the class are fail-fast; if the Map is structurally modified after the creation of the iterator it will throw ConcurrentModificationException. This fact is recorded via the modCount (modification count) whenever an mapping is added or removed.

Hope this helps you understand why a correct implementation of hashCode and equals methods are so important to a class when its objects are used in a collections (based on principle of hashing)  and explains the strange behavior of these collections sometimes.

References

Tuesday 13 September 2011

Immutable classes

An object is said to be mutable when the state of the object can be changed E.x. through the setter methods mostly (of course there are other alternatives to change the state, which we will understand once we step through the guidelines of creating an immutable class). Immutable objects are objects whose state cannot be changed after they are created. Once created their state remains the same till the lifetime of the application (rather every life of the application).


Why would one create an immutable objects?  


  • Immutability objects find their use in concurrent applications/ multi-threaded applications, such an object is always thread safe which means threads wont see an inconsistent state of such an object,so you don't have to synchronize access to them across threads.
  • They also are good candidate in Hash based collections like HashSet  (they need to override equals and hashCode methods). 
  • You can freely share and cache references to immutable objects without having to copy or clone them; you can cache their fields or the results of their methods without worrying about the values becoming stale or inconsistent with the rest of the object's state. 
  • Wrapper classes in java language like Integer, Short, String etc are immutable. 


    So how would you create an Immutable class or what are steps to create one?
    1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
    2. Make all fields final and private.
    3. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
    4. If the instance fields include references to mutable objects, don't allow those objects to be changed:
      • Don't provide methods that modify the mutable objects.
      • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
    References

    Monday 29 August 2011

    Equals and hashcode method

    are two of the most important non final methods in the Object class which if not coded properly can lead to problems when used in collection and are difficult to detect and debug. Hence it is important to understand the contract of the two methods to code for the same.
    Equals method, defined in the object class checks if the references of the objects are the same, i.e they point to the same memory location. You can override this method to check if the two objects are meaningfully equivalent (though residing in different memory location). The following contract needs to be observed while coding the equals method

    • Reflexive - o1.equals(o1), an object should be equal to itself
    • Symmetric -  o1.equals(o2), if and only o2.equals(o1)
    • Transitive -  o1.equals(o2), and o2.equals(o3) implies o1.equals(o3)
    • Consistent - o1.equals(02), returns the same result as long as the objects are not modified.
    • Null Comparison - !o1.equals(null), which means any object is not equal to null, it should return false.
    • Equals and hashCode - If two objects are equal then their hashCode should be equal as well, however the reverse is not true. (It is mandatory to define hashCode if you define equals method)
    HashCode method returns an integer and is supported for the benefit of hashing based collections like HashMap,Hashtable etc. The contract for this method are
    • Consistent - Whenever the method is invoked on the same object more than once during the lifetime of an application, it should always return the same result
    • If two objects are equals as per the equals method then calling the hashCode method in each of the two objects must consistently return the same integer result. If a field is not used in equals method it should not be used in hashCode method as well.
    • If two objects are unequal as per the equals methods then calling the hashCode method in each of the two objects can either return the same or different integer result.

    How to make classes thread safe ?

    What is Thread safety?
    Thread safety is not making a class which implements Runnable or extends Thread, safe.  Thread safety means that the fields of an object or class always maintain a valid state as observed by other objects or classes when used concurrently by multiple threads.


    What are the problems if you don't make a class thread safe?
    Consider a scenario, where two threads are working on the same instance of the class. The object may be undergoing some modification in one thread and at the same time another thread may try to view the state of this object. This object when in thread1 could be in some intermediate state (when it is pre-empted) when thread 2 tries to access it. In this situation, thread 2 is viewing dirty state of the object. To make two threads, view a valid state of the object is when we term that an object is Thread safe.

    When should you think about thread safety?
    Firstly, you should think of thread safety whenever you are working in a multi-threaded application. Java allows multiple threads to be created, hence you think about it whenever you are coding in Java. When you have an instance of a class which can potentially be accessed in multiple threads when undergoing change in state, you should think about thread safety.
    Secondly, as we know all threads share the same heap and memory area, it make it necessary to think about thread safety.

    How can you achieve thread safety?
    Remember? You would not think of thread safety if your object is immutable or is being used in read-only mode,reason: the state of the object cannot be changed or is not changed in these situations.
    So, for sure,we know that making a class immutable (we will discuss in another article how to make a class immutable) or using it as read-only gives us thread safety.
    But, there is a situation where you have to modify the state of the objects then you need to think of thread safety, synchronization the piece of code can help.
    It may also happen that the code that is provided cannot be modified (could be a third party library or your boss does not allow you to play with a tried and tested code), you can still do it by extending the class and making a thread safe wrapper which can be used by the clients of your code. (Example , Collections are not thread safe, you can write thread safe wrapper for collections)


    Points to remember when making the class thread safe
    • Synchronize only the critical code.
    • Instance and static variable are not thread safe, they exist on heap and memory area which multiple threads can access.
    • Local variables,parameters to methods are thread safe.
    • Synchronization comes with performance cost, so synchronize only whats is critical and not the entire method.
    References:



    All about Exceptions

    What are Exception? Well, exception are exceptions, they are not normal and suggest that they should be handled in order for you to proceed forward or else some can be severe that they can cripple your application.

    What are the different types of exceptions?
    Exceptions - are the not so serious types of problem in your code. Some are ones which are known and hence compiler wants you to handle them and take corrective action, these are called checked exceptions and some are unknown at compile time and are hence called unchecked exceptions. Exceptions like ArrayIndexOutOfBoundsException are unchecked exception as they happen at runtime and hence are also termed as RuntimeException.
    Errors - are more fatal, they can bring down your application, you cannot catch them. OutOfMemoryError is once such example, it means that JVM cannot allocate an object because it is out of memory.

    Some points to remember about exceptions

    • All Exceptions are derived from java.lang.Exception or its subclass
    • You can create your own exception by extending the Exception or its subclass (for checked exceptions) or RuntimeException (for unchecked exceptions).
    • Compiler forces checked exceptions to be handled, you either handle them via try-catch block or mention that the method wont handle them and declare them in the throws clause.
    • Runtime exceptions may or may not be handled.
    • Catch blocks are ordered to catch exceptions from more specific to general, else the compiler will complain. Reason, the broader exception class can handle its sub-classes as well and hence it wont make sense to have a more specific exception (which is its subclass) later in the catch block. Ex a FileNotFoundException cannot be caught later in a catch block than IOException, as the earlier is a subclass of IOException.
    • Uncaught exceptions propagate back through the call stack, from the place it was generated to the first method that has the try-catch block, if its not handle anywhere not even in the main method then it will cause a JVM shutdown.
    Some best practices with exceptions
    • Do not use Exceptions as flow controls, exceptions are not alternate routes of flow but are unwarranted scenarios which should be handled.
    • Exception should be thrown early for it to be more accurate and specific, reason the stack trace generated at that point can help you to get to the root cause of the exception as it will contain all the method calls that lead to the exception.
    • Handle exceptions at the appropriate layer. Allow the exceptions to pass through if it makes no sense to handle at a particular layer, don't swallow it with empty catch block or a system.out just because the compiler is cribbing at that point. Instead handle (try-catch) it at the appropriate layer where you can meaningfully recover from the exception and can continue or if not , log it using logging frameworks so that the root cause can be identified and fixed.
    • To create a Checked or Unchecked Exception is a very debatable topic. However if you can recover meaningfully from an exception then throw a checked exception. 
    • Do not create or throw exceptions unnecessarily, reason creating a stack trace is a costly process.


    Saturday 13 August 2011

    Serialization in Java

    In my previous post about cloning there was a mention of serialization. So,

    What is serialization?
    It is the process of reading or writing an object to a stream. Here the object's state is written to a sequence of bytes, this transformation is called serialization. The object state can then be retrieved from the stream of bytes into a live object for use later in the program. This process is called de-serialization.

    What can or cannot be serialized?
    The variables which are marked as static or transient are not serialized all others can be. Static variables are not serialized as the don't belong to any individual object of the class, where as transient construct lets the programmer control which variables need not be serialized. So what happens to these variables when the state is de-serialized; these variables will get the default values.

    When and why would one need serialization?
    Serialization has found its uses in many places
    1. As mentioned in the post for 'Deep cloning and Shallow cloning' we can achieve deep cloning via serialization.
    2. Whenever an object needs to be saved for future use its state can be serialized to a file or database or in-memory and then later de-serialized.(ex object stored in HTTP session should be serializable to support in-memory replication for scalability) NOTE: Though not mandatory but as a convention, when an objects state is written to a file, the file should have an extension of .ser 
    3. To send an object over the network i.e from one JVM to another (ex. objects passed in RMI needs to be serializable to support marshaling and un-marshaling of objects)

    There are three primary reasons why objects are not serializable by default and must implement the Serializable interface to access Java's serialization mechanism.
    1. Not all objects capture useful semantics in a serialized state. For example, a thread object is tied to the state of the current JVM. There is no context in which a de-serialized Thread object would maintain useful semantics.
    2. The serialized state of an object forms part of its class's compatibility contract. Maintaining compatibility between versions of serializable classes requires additional effort and consideration. Therefore, making a class serializable needs to be a deliberate design decision and not a default condition.
    3. Serialization allows access to non-transient private members of a class that are not otherwise accessible. Classes containing sensitive information (for example, a password) should not be serializable nor externalizable. (If there is a need for more control over the process of reading /writing the object to a stream then the class can implement Externalizable)
    Some of the classes which are Serializable in java are the Wrapper classes,String class, Date,DateTime, File etc.

    How can we achieve/JVM helps in serialization?
    An object can be marked as serializable by making the object implement the Serializable interface. It is just a marker interface and has no method which the class needs to implement. (markers help the JVM to understand that the object is of a specific type and needs to be treated accordingly i.e it helps to identify the semantics of being serializable). All subtypes of the Serializable class are themselves Serializable.

    To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields provided  the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case and will be detected at runtime.

    During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

    When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object.

    What do you understand by serial Version ID? 
    The serialVersionUID is a universal version identifier for a Serializable class. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. 

    During the process of serialization all classes are given an unique serial Version ID if it is not explicitly provided in the class. [You can explicitly add a unique ID yourself pro-grammatically or by the use of SerialVer tool.].
    If the identifier of the class and that of the flattened object is not the same then the de-serialization process will throw an InvalidClassException. This can happen if a new attribute is added to the modified class or the class no longer extends the same hierarchy tree , that is, the structure of the class undergoes modification. This  exception could also be thrown when the serialVersionID calculated by different JVM's vary.

    References

    Type casting - Implicit and explicit

    The basics
    Whenever you create a class in java, you create a new data type. You can create instances of these classes  which are referred to as objects. To work with the objects you would need a variable through which you refer the objects, these are called as the reference variable and the object that the variable refers to is called the referred object.

    Creating a reference variable with the java statement
             Employee employee;  (In general ReferenceType reference)
    will not create an object of Employee instead it will just mean that we have created a reference variable for an object of type Employee.
    This reference can hold the value of null or an object of ReferenceType  or any object whose type is subclass of ReferenceType.The reference type could be a interface/abstract class/class. The type of the reference determines how the referenced object i.e the object that is the value of the reference can be used,(you can use the behavior of the referenced object or its superclasses if any).  However, the object type of the referred object determines the behavior of the variable at runtime (FYI, polymorphism).


    So what is casting?
    Type casting happens when one data type is converted to another data type or it simply means treating a variable of one type as though its another type. There are 2 ways a casting can happen 
    1. Upcasting - also called widening conversions. Its easy to convert a subclass to the superclass, reason a subclass object is also a superclass object. Ex casting a SavingAccount object to an Account class variable is automatic.
    2. Downcasting - also called narrowing conversions, this requires an explicit cast and also that the object that is casted is a legitimate instance of the class you are casting too. When you code for explicit casting you tell the compiler, that you understand/take responsibility that the reference variable will hold an object of the reference type or its subclass. The JVM will then check for the correctness of this at runtime.
    You can also cast an object to an interface provided that the object's class or any one of it superclass   implement the interface .

    Casting can be applied to primitives as well. The primitives are placed in the following hierarchy/order,

                 byte--- short---int---long---float---double.  \
    Upcasting happens automatically when you go from left to right, but if you go from right to left explicit casting is required. Ex: Casting a short to a byte is possible, however if the value of the variable of type short exceeds the permissible value that can be handled by byte, then this conversion can lead to an overflow condition at runtime. Remember java does not inform us with exceptions, about overflow or underflow conditions, so care should be taken to understand the overflow and underflow behavior for such numerical conversions and computations.

    When is ClassCastException thrown?
    ClassCastException is thrown when you attempt to cast an object to a class of which it is not an instance.
    Ex You cannot assign an Account object to a SavingAccount variable.   Although you could get away with the compile time error or Type mismatch error by explicit casting; it would fail at runtime with ClassCastException. A Type mismatch error also occurs when you try to reference a object of a different hierarchy. (Ex. trying to assign an employee object to an Account class variable)

    You can deal with incorrect casting in 2 ways
    1. Catching the ClassCastException with the try-catch block
    2. Before casting use to instanceof operator to check if the object being casted is an legitimate instance of the reference type else be sure to deal with it either through the else block or the exception being generated.
    NOTE:
    You could also get a ClassCastException when two different class loaders load the same class because they are treated as two different classes.

    What happens when you assign a reference variable with value null to a specific type. Say,   Account acc = (Account) acc1;  where acc1 is null. Casting has nothing to do with the value of the referenced object it just lets the compiler know that you know what you are doing (refer, Downcasting)

    However, thing to note is when you have overloaded methods Example, myMethod(String s) and myMethod(Integer i) and you want to pass null as a parameter, then you need to explicitly cast so that the compiler knows which method to call, else it cribs saying the invocation is ambiguous.

    Thursday 11 August 2011

    What do you mean by deep cloning and shallow cloning

    Java supports two different types of cloning
    1. Shallow cloning - java's object.clone() gives a shallow copy of the object being cloned. Here the object cloned is copied without its contained object. Shallow cloning is a bitwise copy of an object. New object is created which is an exact copy of the original one. In case  of contained objects just the references are copied.
    2. Deep cloning - as object.clone() method yields shallow copy, to achieve deep copy classes needs to be adjusted (check note below). Here the original object is copied along with its contained objects (note: here the entire graph of objects are traversed and copied.) Each object in the graph is responsible of cloning itself through the clone method.So, In deep cloning, complete duplicate copy of the original copy is created. 
    NOTE
    • If the object wants to be able to clone itself it first needs to implement Cloneable interface else object is going to throw CloneNotSupportedException when the clone method is called. 
    • Second the object needs to make the clone() method public. 
    • Next in the clone method call the super.clone() 
    • You need not do anything special for primitive data types, its wrapper objects and immutable objects like String, the super.clone() method automatically creates a copy of them.
    • When you perform a deep copy involving collections the objects in the collection also needs to implement Cloneable.
    Problems with cloning
    • The entire object graph needs to be cloned, which is tiresome and error prone and difficult to maintain. Care should be taken when there is a modification to the classes.
    • Care should also be taken in circular reference of object, the reference object should be created only once. Ex Say Department contains Employee class and Employee inturn refers Department, care should be taken that the reference department is created only once.
    • If the class is not available for modification (third party classes), and there is a need for cloning, you need to create a new class by sub-classing and then overriding the clone method.
    • Also its problematic to clone a polymorphic variable, as the decision has to wait till the runtime.
    Alternatives to cloning
    Java Serialization offers an alternative for cloning (key here is the object and all the referenced objects needs to be serializable), here the entire object tree is traversed and serialized, and de-serializing it later will yield the exact state but a different copy of the original serialized object. However the cost of serialization is its performance, as this involves writing and reading from the stream.


    References

    Saturday 6 August 2011

    Garbage collection in Java

    What is garbage collection and who handles it?
    is the process of collecting unused/unreachable objects (i.e those objects who have lived their life in the lifetime of a program and whose non existence does not affect the continuity of the program). Java handles memory de-allocation through garbage collection. There is a low priority daemon thread called the Garbage Collector thread which runs in the background performing this task of collecting unreachable objects. It runs in low memory situations to reclaim unused memory. Garbage collection cannot be forced, you can request the JVM to perform GC through System.gc(), but there is no guarantee that it will be a synchronous call or it will happen immediately on call.


    Why does GC happen?
    Whenever the JVM runs low in memory /or during certain time intervals, the garbage collector thread will wake up and try to reclaim unused memory by de-allocating memory referenced by unreachable object. Every programmer must have experienced a behavior of sudden unresponsiveness in the lifetime of a program. These are times when the garbage collector is doing its job of reclaiming memory. If the JVM cannot create an object on the heap it will fail with OutOfMemoryError.


    When does an object become eligible for GC?
    We know that in java an object that gets created, lives on the heap, whether the object is a local variable or instance variable, where as class or static variables live inside the memory area (fyi).
    When an object becomes unreachable it becomes eligible for GC. (i.e no live threads or static references point to these object)
    So when does object become unreachable.

    1. When you explicitly assign all references to an object to null, stating that the object has served its purpose and is no longer needed.
    2. Object goes out of scope once the block of code in which it is created gets executed.
    3. Cyclic references are detected by garbage collecting algorithms and hence become automatically eligible for garbage collection as long as there are no other live object referencing these objects.
    4. When the container object is set to null , the contained objects become eligible for GC.
    5. All weak reference gets eligible for GC in the next GC cycle.

    References

    How does JVM handle synchronization?

    Introduction
    We have seen how the JVM organizes the program into runtime data areas in my previous blog. We know that each thread has its own stack and that all the threads in the program share the heap. The heap contains all the objects created within the program including the thread. The method area contains all the class /static variables of a classes used by the program. These variables are available to all the threads in the program.

    Now we know that we have two data areas which contains data shared by all threads.
    1. the heap and 2. the method area

    Monitors
    So if two threads try to access the objects or class variables in these areas concurrently, then the data need to be properly managed else we will end up with inconsistent data. This situation can be handled through synchronization and java manages this through the use of 'monitor'. Hence monitor acts as a guardian over a piece of code, so that no two threads execute that code simultaneously.
    Java's monitor supports two kinds of synchronization: mutual exclusion and cooperation

    • Mutual exclusion is achieved in JVM through the use of object or class blocks , they enable multiple threads to work independently on shared data without interfering with  each other. 
    • While Cooperation in JVM is achieved through the use of object wait, notify and notifyAll methods.

    Each monitor is associated with an object reference. Whenever a thread reaches the code which is synchronized, it must obtain a lock on the referenced object failing which it will have to wait (block on synchronization state). Once the thread obtains the lock the JVM increases the count of the number of times an object has been locked. The same thread can lock the same object multiple times. Whenever the thread releases/relinquishes the lock the count is decremented. When there are no more locks on the object i.e count returns to zero, then any other thread can obtain the lock on the object if needed.

    Synchronization is supported by the java language  in two ways

    1. synchronized method : Whenever the JVM encounters a symbolic reference to the method and realizes its a synchronized method, then it tries to obtains the lock from the monitor. If the lock is obtained then the synchronized method is executed and once all the statements are processed or the code throws an exception the lock is released. For an instance method, a lock is obtained on the object, of which synchronized method is invoked. In case of static synchronized method the lock is obtained on the class object. The JVM does not use special op-codes to invoke or return from method level synchronization.
    2. synchronized statement (Block of code): The JVM uses two special op codes monitorenter and monitorexit whenever a thread enters or exits the synchronized block of code. When the JVM's encounters monitorenter  it tries to obtain a lock on the object referred to by objectref on the stack. If the lock is already obtained the the count is incremented by one and whenever the monitorexit  is encountered the count is decremented by one. When the count reaches zero the lock is released.

    References



    Friday 5 August 2011

    Synchronization in Java

    What is synchronization?
    Threads communicate with each other by sharing access to fields and the objects reference fields refer to. (concurrent access to shared data).Though efficient, it can lead to thread interference and memory consistency errors. The tool to avoid these kind of errors in java is synchronization.

    Why do we need to synchronize?
    As said earlier, to avoid
    1. Thread interference: happens when two methods/operations running in two different threads but acting on same data, interleave.(i.e the sequence of steps interleave)
    2. Memory consistency errors:  occur when different threads have inconsistent views of what should be the same data.
    Through the use of synchronization we can avoid the problem of  dirty data (This happens when the shared object is mutable) caused by multiple threads acting on the same data.  To avoid this, java uses monitors and 'synchronize' keyword to control access to a mutable shared object. Synchronization is not needed if you are using an immutable shared object or the shared object is used in read only mode.

    What are the different ways/levels of synchronization can be applied in Java?
    The synchronize keyword can be applied at the method level (coarse grained) or block of code (fine grained). 
    • If the keyword is applied to a static method then the lock is obtained on the class object (ex Account.getClass()).
    • If the keyword is applied on a non static method, then the lock is obtained on the instance of the object which contains synchronized code (ex obj1).
    Any code which is written in the synchronized block has mutually exclusive lock on the object; which means that no other thread can access this critical section except the thread which is holding the lock. All other threads will have to wait till the lock is released.
    It is usually a good practice to synchronize only that section of code which is critical rather than blocking the entire method ; reason synchronization comes with a performance cost.


    Disadvantages of synchronization 

    1. There is a possibility of dead locks if not coded properly.
    2. Another problem with using it is performance; there is an overhead of obtaining locks.
    References

    Thursday 4 August 2011

    Threads in Java

    What is a thread?
    Thread is a lightweight process i.e single sequential flow of control within the JVM process (when you run the java command at the prompt it creates the JVM to run the application; the name of which you supply as parameter to the java command Ex. java com.test.MainApplication).This process can have multiple threads created within.
    As discussed in my previous blog article, a thread shares the heap (place where the object created within the application resides) belonging to the process and has its own stack space. Multiple threads share the heap and hence care should be taken than the objects accessed are thread safe.

    Ways to create thread?
    There are two ways to create thread
    1. Extend Thread class : and override the run method from Thread class
    2. Implement Runnable interface: It has one method public void run() which the implementing class should define.
    One should implement Runnable interface to get threading behavior instead of extending Thread. One should extend Thread only if the intention is to extend the behavior of the existing Thread class.

    Why do we need to create Thread? If you want parallel processing of tasks and these tasks are independent of each other then we can achieve this using Threads. If there is critical data that is used by multiple threads and changing it in one thread can cause data inconsistency in the other thread then one should synchronize the critical section of code. More on synchronization in my next post.


    Different states of a thread?
    The life cycle of the thread will begin when the client code call the start() method on Thread. Creating a thread using the new operator will not start the thread.Threads can be in one of the following states once it started,
    1. Runnable : When you start the thread using t.start() the thread goes into the Thread pool, following which the ThreadScheduler can pick this ready to run thread for execution. A thread can be in this state  in others ways too. Please refer to the diagram for the same.
    2. Running: Current executing Thread is said to be in this state. It will be in this state till it is swapped by Scheduler or its blocked for IO or enters synchronization code or it relinquishes with the static Thread.yield method or goes to sleep with the Thread.sleep method.
    3. Waiting: execution of the object.wait() method causes the current thread to go into wait state.The current thread should hold the monitor for invoking the wait method. It will remain in this state till some other thread, notifies the thread by calling notify() or notifyAll() method. 
    4. Sleeping: A call to the Thread.sleep(long milliseconds) method causes the current thread to sleep or suspend its operation for the predefined time specified in the sleep method call. After the time elapses it will move to Runnable state and will begin execution when the ThreadScheduler will it pick it.
    5. Blocked: Thread can go into this state while performing an I/O operation,  or while waiting for the lock when entering a synchronized method or block of code; once the I/O operation completes the thread or when the lock is obtained the thread will move into the Runnable state.
    6. Dead:  Once the thread finishes execution or there is error/exception in the run method a thread will enter the dead state. Please note: A dead thread cannot be revived again by a call to the start() method.
    Thread and deadlock
    In case of multiple threads, there are chances that the following may happen

    • Deadlock occurs when two or more threads are trying to gain lock on the same object, and each one has a lock on another resource that they need in order to proceed. For example, When thread A waiting for lock on Object P while holding the lock on Object Q and at the same time, thread B holding a lock on Object P and waiting for lock on Object Q, deadlock occurs.
    • If the thread is holding a lock and went to a sleeping state, it does not loose the lock. However, when thread goes in blocked state, it normally releases the lock. This eliminates the potential of deadlocking threads.
    • Java does not provide any mechanisms for detection or control of deadlock situations, so we as programmer are responsible for avoiding them.

    Resources:

    Thursday 28 July 2011

    Best practices while using collection API

    The following are some best practices that one can follow while using collection API (as discussed in various blogs and books)

    1. Code to interfaces rather than implementation; reason, you can change the implementation later on without significant effect.
    2. Set the initial capacity of the collection appropriately, if you know the size you can gain on speed, else these collection classes will have to grow periodically when the size hits the limit.
    3. Use ArrayList, HashMap etc as opposed to Vector and Hashtable; reason,Vector and Hashtable methods are synchronized, if you want synchronization using ArrayList, HashMap then you externally synchronize the same. I will show that in my next blog.
    4. Return zero length collection or array as opposed to returning NULL; to avoid running into NullPointerException issues at runtime.
    5. Immutable object should be used as keys for the HashMap; so also as values in a HashSet. 
    6. Encapsulate collections; to avoid unintentional  modification of the collections.
    7. Stored related objects together and avoid storing unrelated or different types in the same collection.

    Overriding and overloading a method

    So what do we understand by these two terms.

    Overriding, lets you define the same method in different ways for different object types in an hierarchy (i.e  when there is inheritance, hence we can say a subclass can override the behavior defined in the super class). The general rules to override a method are
    1. The method MUST have the same argument list.
    2. The method MUST have the same return type.
    3. The access modifier CANNOT be less restrictive
    4. The new method should not throw new and broader exceptions; it can throw less, narrower and run-time exception. If you throw broader exception; you violate the contract defined in the super class and and also you will loose the message the actual exception has to offer  
    5. Selection among overridden methods is dynamic (decision at run-time based on the object type).
    In overloading,overloading lets you define the same method in different ways for different data in the class or its subclass. The general rules to overload a method are.
    1. The method MUST have different arguments (the number of arguments/type of argument can vary)
    2. The return type CAN be changed
    3. The access modifier CAN be changed
    4. The new method CAN throw different exceptions list.
    5. Selection among overloaded methods is static (made at compile time). Ex Say you have two methods print one which takes argument as Object and another print method which takes String. When the client invokes the print method with a string "Test"; then the print method which takes String will get invoked even though String extends Object, reason the decision to call the method happened at compile time. i.e  someObject. print("Test").
    References
    • Effective Java  - Joshua Bloch.


      Tuesday 26 July 2011

      Comparable versus Comparator

      Comparable and Comparator are both used to compare objects.

      In case of Comparable interface,
      1. The object o1 (class of which implements the interface) is compared to the object o2 which is passed as method argument [NOTE: public int compareTo(Object o2) ]
      2. If the o1 is greater than o2 then the method will return +ve integer and -ve if lesser than o2, if both are equal then 0 value is returned.
      3. It should be used when you want to define natural/default ordering of a class, if the class is available for modification (remember? a third party class isn't available for modification)
      4. if one add two keys a and b such that (!a.equals(b) && a.compareTo(b)==0) to a sorted set that does not use an explicit comparator, then the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.
      In case of Comparator interface,
      1. The Class which implements this interface will take two objects and compare them with each other. [NOTE: public int compare(Object o1, Object o2)
      2. If the o1 is greater than o2 then the method will return +ve integer and -ve if lesser than o2, if both are equal then 0 value is returned.
      3. If the class isn't available for modifying or if you want to define ordering which is other than the default then use the Comparator interface.
      4. If one add two keys a and b such that (a.equals(b) && c.compare(a,b)!=0) to a sorted set with comparator c, then the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.
      Resources

      Monday 25 July 2011

      Abstract class and interface

      When to create abstract class?
      We create an abstract class when there is some common behaviour which can be reused across subclasses and certain behaviour needs to be defferred to the sublasses as they are subclass specific. We define such a behaviour using the abstract construct in java. Abstract classes help us achieve implementation inheritance.
      When to create an interface?
      When the client is only concerned with the behavior and does not worry about the actual implementation, then we should model such behavior using interface. Interface helps us achieve polymorphic interface inheritance.

      So having said that,
      1. Abstract classes should be used when there is a strict heirarchy of classes i.e there is strict IS-A relationship between the classes. Ex FlatFileReader/XMLFileReader extends FileReader method loadFile is common behaviour and the procedure to load a flat file versus a XML file is the same however readFile can be sublass specific given the file types. With interface you can relate classes which are otherwise unrelated.
        Ex SoundBehaviour interface with method makeSound() can relate a Animal Class heirachy and Instrument class heirachy.
      2. Abstract classes should be used in cases where the base class needs to be changed often, the subclasses will inherit the behaviour without any change.Use of interfaces in such a case will make the design fragile, as changes to interfaces will be propogated to implementing classes.
      Resources

      Sunday 26 June 2011

      Inheritance versus composition in Java

      are two important concepts you should swear by. Both help us to relate classes and achieve code resuse. But which one do we use?
      Comparing inheritance and composition.
      1. In inheritance, a change to the method interface/definition of the superclass ripples down to the sublasses (if the method is overriden) and also to the clients of the sublasses thus making the superclass very fragile. In case of composition the change is limited to the containing class and not the clients.
      2. With inheritance, you cannot change the overriden method in the subclass without changing the superclass; reason it wont compile. With composition, you can change the interface of the method in the containing class that uses the method/behaviour of the contained class without touching it.
      3. In case of inheritance the classes are bound statically at compile time or as soon as the subclass is defined and will remain with the subclass till its lifetime. where as in case of composition, the behaviour can be changed at runtime.
      4. Though, with inheritance you can add new subclasses without affecting the code. Where as this is not the case with composition, unless you use composition with interface.
      Going by the definition of inheritance, one should use it only if there is a IS-A relationship between classes and should not be merely used to get code re-use or polymorphism.
      If you want to reuse code and there is no IS-A relationship , use composition and if you need polymorphism, but there is no IS-A relationship, use composition with interfaces.

      I will add examples to explain each comparison points, in my next iteration of this post.
      Resources

      Friday 24 June 2011

      Class Loaders - simplified - part 2

      In my last post I said I will be discussing about NoClassDefFoundError and the ClassNotFoundException

      You can load the classes in two ways one is static loading and second way is to dynamically loading the class.
      1. Static loading - load a class statically using the new operator.
      2. Dynamic loading - programmatically loading the class using the class loader functions at run time.Using Ex Class.forName/ClassLoader.findSystemClass/ClassLoader.loadClass
      You can get NoClassDefFoundError for the following reason
      1) You have not set the class path, so the class loader cannot find the .class file ( TestClass)
      2) You have set the class path, but the class path does not contain the .class file/jar does not contain the specified .class (the call to the new operator fails)
      3) It could also happen if the class fails to load as the static initializer block fails for some reason.

      You can get ClassNotFoundException if
      1) You have set the class path, but the class path does not contain the .class file/jar does not contain the specified .class , so the dynamic loading call class.forName fails.


      Use the below example of a class that tries to refer to another TestClass

      public class ClassLoaderExceptionTest
      {
      public static void main(String args[]) throws Exception
      {
      //Try1
      Class class = Class.forName("TestClass"); //dynamically loading the class
      //Throws ClassNotFoundException if TestClass is missing or removed after compilation/ not present in //class path
      //Try2
      TestClass testClass = new TestClass(); // static loading
      //Throws NoClassDefFoundError if TestClass is missing or removed after compilation/ not present in class //path
      }
      }
      class TestClass{
      }

      Thursday 23 June 2011

      Class Loaders - simplified - part 1

      As discussed in my previous post, class loaders is one of the components of JVM. It is responsible for finding and loading the class at run time.

      Classes are loaded into the JVM as they are referenced by name in a class that is already running in JVM. The first class is loaded into memory by invoking the static void main method of the class. All subsequent classes are loaded by classes which are previously loaded and running.

      The following class loaders are created by the JVM
      1. Bootstrap or primordial class loader: Is the default class loader which is associated with the JVM. You can hook your own custom class loader instead of the default. All the JDK internal classes java.* packages i.e the ones that belong to rt.jar or i18n.jar are loaded by this class loader. (as defined in the sun.boot.class.path system property)
      2. Extension class loader: loads classes that are part of the extensions directory typically the lib/ext directory of the JRE are loaded by this class loader. (as defined in the java.ext.dirs system property)
      3. System class loader: loads classes that are part of the system class path (as defined by the java.class.path system property which is set by the CLASSPATH environment property, or -classpath / -cp command line options)
      Classes loaded by different class loaders are placed into separate name spaces inside the Java virtual machine.
      Class Loaders not just loads but performs the following activities in sequence.
      1. Loading - finding and importing the binary data of the type in the .class file.
      2. Linking - involves verification, preparation and resolution.
        • Verification - involves ensurinNumbered Listg that the binary data is structurally valid, else will throw VerifyError.
        • Preparation - involves allocating memory for class variables and initializing the memory to the default values.
        • Resolution - is the process of transforming the symbolic references from the type into direct references.
      3. Initialization - invokes code that initializes class variables to their proper starting values.
      Class loaders use delegation model to load classes. Whenever a class requires to be loaded, the class loaders will contact its parents to load the class before they themselves try. Once the class loaders loads the class, the child class loader in the hierarchy will never reload the class. Classes loaded by the child class loaders have visibility into the classes loaded by parent class loaders but the reverse is not true. If there are sibling class loaders, then the sibling class loaders do not see the classes loaded by each other.


      More on class loaders in my next blog. I will cover scenarios when you would encounter NoClassDefFoundError and ClassNotFoundException.