Wednesday, April 11, 2007
Instantiating a java Object bypassing constructor
One more interesting fact i have come across today is we can instantiate a java object bypassing a constructor.
We have a class which have a constructor with some arguments and doesn't contains no argument constructor. If we try to create a object by calling default constructor it will throw an error.
Below example shows what i have said above.
class PersonalDetails {
private String fname;
private String lname;
private int id;
public PersonalDetails(String fname, String lname, int id){
this.fname=fname;
this.lname=lname;
this.id=id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
}
public class Instantiation
{
public static void main(String[] args) {
PersonalDetails personalDetails = new PersonalDetails();
}
}
When tried to run, it will give the following error
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor PersonalDetails() is undefined
at Instantiation.main(Instantiation.java:45)
But with Objenesis we can create a object bypassing constructor.
Below example shows how to create a object bypassing constructor.
import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import org.objenesis.instantiator.ObjectInstantiator;
class PersonalDetails {
private String fname;
private String lname;
private int id;
public PersonalDetails(String fname, String lname, int id){
this.fname=fname;
this.lname=lname;
this.id=id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
}
public class Instantiation
{
public static void main(String[] args) {
Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
ObjectInstantiator pDInstantiator = objenesis.getInstantiatorOf(PersonalDetails.class);
PersonalDetails personalDetails =(PersonalDetails)pDInstantiator.newInstance();
System.out.println("fname="+personalDetails.getFname()+" | lname="+personalDetails.getLname()+" | id="+personalDetails.getId());
}
}
Output:-
fname=null | lname=null | id=0
Note:- objenesis.jar is required for the above program to work. You can find the jar in the link provided below
Below link contains much more info about Objenesis.
http://objenesis.googlecode.com/svn/docs/index.html
Tuesday, April 10, 2007
Accessing and Modifying Private and Final variables in java
In the office, today, i got into a situation where i have to access private members of a java class without setters and getters.
Initially i thought its impossible!! As usual searched in google.
Below is the epitome of my findings.
In fact, we can access not only private variables but also modify them.
One more interesting fact is that we can modify final variables.
We can achieve this through Reflection.
Only Exception to this is we cannot access or modify static final variables.
Below example explains everything.
Class PersonalDetails contains a static private, a final private and a private variable.
import java.lang.reflect.*;
class PersonalDetails {
private static String fname = "Ravi";
private final String lname="Sankar";
private int id = 123456;
}
public class ReflectionAbuse
{
public static void main(String[] args) throws Exception {
PersonalDetails personalDetails = new PersonalDetails();
Field fnameField = PersonalDetails.class.getDeclaredField("fname");
Field lnameField = PersonalDetails.class.getDeclaredField("lname");
Field idField = PersonalDetails.class.getDeclaredField("id");
/** Setting Accessible to true to access the variables */
fnameField.setAccessible(true);
lnameField.setAccessible(true);
idField.setAccessible(true);
/** Accessing private and Fianl Variables */
String fname = (String)fnameField.get(personalDetails);
String lname = (String)lnameField.get(personalDetails);
int id = idField.getInt(personalDetails);
/** Before Setting: Printing the values */
System.out.println("fname="+fname+" | lname="+lname+" | id="+id);
/** Modifing Private and Final Variables */
fnameField.set(personalDetails, "Anil");
lnameField.set(personalDetails,"Kumara");
idField.set(personalDetails,987654);
fname = (String)fnameField.get(personalDetails);
lname = (String)lnameField.get(personalDetails);
id = idField.getInt(personalDetails);
/** After Setting: Printing the values */
System.out.println("fname="+fname+" | lname="+lname+" | id="+id);
}
}
Output:-
fname=Ravi | lname=Sankar | id=123456
fname=Anil | lname=Kumara | id=987654
If we try to modify value of a static final then it will throw java.lang.IllegalAccessException:
exception
References:-
http://www.roseindia.net/javatutorials/jdk5_final_is_not_final.shtml
http://www.javalobby.org/java/forums/m91815224.html
Subscribe to:
Posts (Atom)
