Thursday, March 28, 2013

Java - Way to create an Object



There are not so many ways in java to create an Object. There are only four way so there is no need to get hectic. The article what deals is a developer point of view.  Below are the ways –
1.      Using “new” java operator.
2.      Using clone () method, that comes with Object class.
3.      Using De-serialization (verities about “new” operator).
4.      Using “forName ()” (respect with newInstance() and ClassLoder).
Now going details about the object creation way –
1.      Using “new” java operator – this is the most commonly way to create an object, I think it’s 95 to 99% of time to use to create an object.  Like other operator “new” is a java operator that is used to create an object. This is an operator that requires a constructor operand that is used to initialize a new created instance.   This operator is used to allocate the memory space and initialize the fields with their default values and then execute the only operand constructor and execute its instructions and if requires then re-write the instance variables values.  For instance –

2.      Using clone() method -  Clone is a Greek word meaning “branch”, referring to the process whereby a new plant can be created from a twig. In biology it is about copying the DNAs. In java, though clone is ‘intended’ to produce a copy of the same object it is not guaranteed. Clone comes with lots of its and buts. Cloning does not call the “new” operator internally. Objet class’s clone method is a native method which translates into instructions for allocating the memory and copying the data. As I said that clone does not call “new” operator that means there would be some differences between them. As we know that “new” operator does three tasks - allocating the memory, initializing the fields with default values, and calling the specified constructor. But in case of cloning the allocated memory is not initialized with default values and also no constructor is called in this case only a data copy instruction executes which copies the data from the original object to the cloned object. One more thing that I want to say here that even if we override the clone() method either to implement deep cloning or to make the clone method as public  'public' but then also we keep the line super.clone() inside the overridden definition which ultimately calls Object.clone() method only. There are two terms in cloning one is Shallow and deep cloning.
3.      Using De-serialization (verities about “new” operator) – this is another way to create an object in java. This internally uses the “new” operator to create an object. Now a question comes in mind that if it calls internally “new” operator then what is the difference from approach 1st?  It does use the 'new' operator internally and always calls the default constructor. But two noticeable differences between the two approaches are: - In case of an explicit 'new' call we may specify any constructor which is not the case here. It'll always invoke the default constructor. Another difference is that in this case the newly created object is initialized (or better to say re-written as the implicit 'new' call with default constructor would have already initialized the object first with the default value and then with the specified value in the default constructor) with the data from the Input Stream fetched usually from a persistent medium. This step is obviously not involved in an explicit 'new' call.
4.      Using “forName ()” (respect with newInstance() and ClassLoder) - A class can be dynamically loaded using the Class.forName() method. This method has two variants  -
1.      Class.forName(“ClassName”);
2.      Class.forName(“className”, initialize, classLoader);

First one which accepts only a String type parameter which is the qualifies name of the class to be loaded and the other variant expects three parameters - the String type qualifies class name, boolean type flag to specify if the class should be initialized, and the ClassLoader name which should be used to load the class. But the former type also internally calls the three-parameter variant only by assuming the boolean flag as 'true' and the ClassLoader as returned by the getClassLoader() method. That means 'Class.forName("qualified.ClassName")' is internally translated into 'Class.forName("qualifies.ClassName", true, this.getClass().getClassLoader())'. Once the class has been loaded then a call of the method newInstance() on the loaded Class object will first check if the Class object is initialized or not and if not then it will initialize the Class object and create a new object as if the “new” operator has been called with the default constructor of the class under consideration. Again a question round in mind how this is different from an explicit “new”  call and it won't take much of an effort to identify the most obvious difference between the two as the inability of this approach to call any other constructor except the default constructor. Another difference is that the newInstance() call may throw a SecurityException as well because it checks if a Security Manager is installed or not and if it finds a security manager then it checks for access to the class as wellas to the package (if any package specified in the qualified name). Either of two checks may throw a SecurityException. This step is obviously not involved with an explicit 'new' call. Another slightly different way of object creation is by using the loadClass() method of the ClassLoader class which returns a Class object of the specified class and then on the returned Class object we may call newInstance() method to create a new object. I've not put this as a completely separate way because I think Class.forName() method also internally calls this method only - either for the explcitly supplied ClassLoader or for the implcitily obtained ClassLoader as discussed above. What's the difference between the two approaches then? The only difference which I can see is that the former checks for the access to the class (and package) and hence it may throw SecurityException if a Security Manager is installed. But the latter doesn't do these checks and hence doesn't throw SecurityException. It's normally advised not to call the loadClass() method directly as almost always you can call Class.forName() by supplying the particular ClassLoader reference.

No comments:

Post a Comment