Sunday, 19 May 2013

Accesing private variables using Reflection API

Reflection API in Java comes very handy to test class variables and methods at runtime. You can call it a type of hack as it violates the principle of Data Encapsulation. Let us see a code that demonstrates how can we access private variables using Reflection API and even edit it.

Code :


public class Someclass {
    private String name = "John";

}

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String args[]) throws Exception
    {
       
Someclass myClass = new Someclass();
        Field fs = myClass.getClass().getDeclaredField("name");
        fs.setAccessible(true);
        System.out.println("Variable is " + fs.getName() + " and value is " + fs.get(myClass));
        fs.set(myClass, "Sam");
        System.out.println("Variable is " + fs.getName() + " and value is " + fs.get(myClass));
    }
}

Output :  



Explanation : 

          Note that the private variable name is in the Someclass class and our main method is in the Test class. According to OOP principles we should not be able to access the private variable name. Using the instance of the class myClass we get the declared field with name name. Then we set it accessible property to true. Then we can access it and print it(as shown in the output). Moreover we can also change it's value using Reflection API. fs.set(myClass, "Sam") method does that.

For more details you can refer to it's documentation.
  

Saturday, 18 May 2013

Hashtable example in Java.

In last post we saw difference between a HashMap and a Hashtable. Let us now see what Hashtable is and how do we use it.

If you see the source code implementation of Hashtable it is similar to that of map. Infact Hashtable implements Map interface.As of the Java 2 platform v1.2, this class was retrofitted to implement the Map interface, making it a member of the Java Collections Framework. For more information refer to Hashtable JavaDocs.

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
{...

Lets see how can we use Hashtable.

Code : 

package testCodes;

import java.util.Enumeration;
import java.util.Hashtable;

public class HashtableDemo {
    
    public static void main(String args[])
    {
        Hashtable<String, String> hashTable = new Hashtable<String, String>();
        //Populating Hashtable
        hashTable.put("Name", "John");
        hashTable.put("Country", "USA");
        hashTable.put("Gender", "Male");
        //Printing whole table
        System.out.println("hashTable : " + hashTable);
        //printing individual values
        Enumeration<String> data = hashTable.keys();
        while(data.hasMoreElements())
        {
            String str = (String) data.nextElement();
            System.out.println(str + " : " + hashTable.get(str));
        }
    }    
}

Output :


Understanding the code : 

     Code is very much similar to HashMap usage but has slight variations. Note Hashtable is a class and not an Interface. put() and get() method remain the same as that of HashMap. What is different is the concept of Enumeration. As specified earlier when Hashtable was introduced there was no Collections and hence no iterators. What we had to use was Enumeration. Enumeration is similar to Iterator. We check whether it has more elements using hasMoreElements() function, if yes access the next element using nextElement() function. Note the use of generics remain the same.

Few very common differences between a HashMap and a Hashtable are -
  • Hashtable is synchronized where as HashMap is not.
  • Hashtable does not allow null keys or values whereas HashMap allows one null key and any number of null values.
  • keys() method of Hashtable return Enumeration where as keySet() method of HashTable returns a Set which can be iterated over as it implements Iterable interface - Enumeration does not.

 Related Links

Interview Question #12 Differences between HashMap and Hashtable?

There are several differences between HashMap and Hashtable. Hashtable was introduced earlier whereas HashMap is a newly introduced as a part of Java Collection Framework.

  • Hashtable is synchronized whereas HashMap is not.This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.
  • Hashtable does not allow null keys or values. HashMap allows one null key and any number of null values.
  • One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for a LinkedHashMap. This wouldn't be as easy if you were using Hashtable.
If synchronization is not an issue for you HashMap is recommended. If synchronization becomes an issue, you may also look at ConcurrentHashMap.


Related Links

Interview Question #11 How to make an object/class immutable and Why?

Background

This is a very interesting question. To give some background let me give an example - String Object in Java. You must have used it a lot but did you know that Strings are immutable. This means once you create a String object you cannot modify it.

Next obvious question that may arise is How do I get different String when I use methods like concat() or substring() ? The answer is you get a different String but not the modified one. Once desired operation is carried out and the result is computed a new String is created with this result and returned.You simply cannot edit a String instance which makes it immutable.

   Having the background information let us now get back to our original question - How can we make such an immutable object/class?

How to make an object/class immutable?

  • First thing that we can do is make the class itself final. This means this class cannot be sub classed any further. So you can start with - public final class Person{
    }
  •  Secondly make any data that you have in your class final. For example if you are creating a Person class  you can define name, age, DOB etc Final.

        final String name;
        final int age;
        final String DOB;
    

    Once this is done you can be sure that the data will not be modified once it is initialized. But how do we initialize the data? We cannot use setter methods as final data cannot be modified.Hence we go for 3rd point.
  • Now create a constructor with these data as arguments and initialize the data.
    Now your class will look like -


    public final class Person {
        private final String name;
        private final int age;
        private final String DOB;
    
        public Test(String name, int age, String DOB) {
            this.name = name;
            this.age = age;
            this.DOB = DOB;
        }
    }
    
This will make your class/object immutable. You can simple create object by saying Person p = new Person("John",21,"12/7/1991");
If you do not wish anyone to instantiate your class. You can provide a method like get public static Person getInstance(String name, int age, String DOB). Inside this function you can create an object of type Person and return it. You can also make your class singleton by checking if any instance already exists. There are many things you can do as per your implementation but the points mentioned above are sufficient to make a class/object immutable.

There can be more follow up questions like why would you make a class immutable?

Why prefer immutable object?

All atomicity and visibility issues that arise from multithreading are due such as race conditions, getting stale value, inconsistent state etc are due to multiple threads trying to access a mutable instance. If the instance is immutable these issue do not arise. Immutable objects are inherently thread safe.

NOTE :  Immutable objects are always thread safe.

Summary

  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. 

Related Links

Sunday, 12 May 2013

How to iterate over a Map in Java?

Just to revise basic of Map go through it demo code. We will use the same piece of code and iterate over it.Purpose of this post is to demonstrate how can we iterate over a Map. We know Map interface does not implement Collection interface and hence we cannot just say someMap.iterator() . To revise Iterators refer to the post on understanding Iterators.Lets see then how do we iterate over a Map.

Java Code : 

package testCodes;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MapDemo {

    public static void main(String args[]) {
        Map<String, String> persononalData = new HashMap<String, String>();
        // Populating Map with data
        persononalData.put("Name", "John");
        persononalData.put("Country", "USA");
        persononalData.put("Gender", "Male");
        persononalData.put("Age", "18");
        Iterator<Map.Entry<String, String>> mapIterator = persononalData
                .entrySet().iterator();
        while (mapIterator.hasNext()) {
            Map.Entry<String, String> keyValuPair = mapIterator.next();
            System.out.println("Key is " + keyValuPair.getKey());
            System.out.println("Value is " + keyValuPair.getValue());
        }
    }
}

output :


Understanding the code : 

 As Map is not a Collection we cannot use .iterator() function on it. What we do is we create a set of Entry objects and iterate over it. Internally key-value pair are stores in Entry objects in the Map. We then get iterator of this set and iterate over it. Entry object has key and values stores in it and we can extract them using .getKey() and .getValue() methods.

Smarter Way : 

        for (Map.Entry<String, String> keyValuePairs : persononalData
                .entrySet()) {
            System.out.println("Key is " + keyValuePairs.getKey()
                    + "and value is " + keyValuePairs.getValue());
        }

This is a bit smarter way to do the same iteration. Internally it does the same thing i.e use a iterator and iterate over the Entry set.This may look a bit complex for beginners. So method mentioned above is recommended.

 What if I only wish to iterate over keys or just values?

             Yes there is a way to specifically iterate over keys and values in Map. The .keySet()  function will return a set of keys where as .values() function will return Collection of values.Note once you have the Set you can get it's iterator and iterate over it's values.

Iterate over keys : 

        for (String key : persononalData.keySet()) {
            System.out.println("Key is " + key);
        }

Output : 

Key is Name
Key is Age
Key is Gender
Key is Country

Iterate over Values : 

        for (String value : persononalData.values()) {
            System.out.println("Values is " + value);
        }

Output : 

Values is John
Values is 18
Values is Male
Values is USA

Note : Keys in a Map are unique and hence .keySet() will return a set. Two different keys can have same value and hence values can't form a set(Values in a set are unique) and hence what you get from .values() is a Collection.

Related Links

t> UA-39527780-1 back to top