May 18, 2012

Accessing Private Member From Other Class In Java

Core Java
Many people wonder if a private field can be accessed from other completely strange class. The words that first come out from the mouth many, if asked whether access to such private members is possible, is: 'impossible!' or say the least: 'you can't do that!'. We are not talking about using accessors here, the usual getter/setter methods are completely excluded. The truth about that is, gaining access to private members from an alien class is not only possible, but real.
And this become possible since the introduction of Reflection in Java. java.lang.reflect APIs provides a utility methods for accessing private members or methods from anywhere. Only defining a security manager can prevent that access. The following program is evidence enough to confirm that.

MyPrivate.java Class


package codecypherprojects;

/**
 *
 * @author khamis
 */

//myPrivate class

public class MyPrivate{
 private int x;
 public myPrivate(){
   x = new Integer(20);
      System.out.println("the value of x is " + x);
  }
}
This is a completely independent class with a private field namely 'x', let us see whether we can access that field from our second class. Creating an instance of this class should print the value of our private field.

MyAccessor.java Class


package AccessingPrivate;
/**
 *
 * @author khamis
 */
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
import AccessedPrivate.myPrivate;
/**This class breaks into myPrivate's field and change its value.*/
public class  MyAccessor{
 public myAccessor() throws IllegalArgumentException, IllegalAccessException, 
   InstantiationException{
   try {
        /**
        * instantiate myPrivate class to get its value printed on the console
        */
       myPrivate c = myPrivate.class.newInstance();
       /**
        * get the decleared field
        */
       Field field = myPrivate.class.getDeclaredField("x");
       /**
        * make it accessible to our class [myAccessor]
        */
       field.setAccessible(true);
       /**
        * are we having the accessibulity yet? isAccessible should return true
        */
       System.out.println("Accessibility is :" + field.isAccessible());
       /**
        *print the accessed x, as decleared in myPrivate class
        */
       System.out.println("The field \"" + field + "\" is now accessible 
         to this class");
       /**
        * pull the value of x out to our new variable
        */
       int theX = field.getInt("x");
       if(theX!=0){
           System.out.println(theX.intValue);
       }
       else
       {
          System.out.println("theX has 0 value");
       }
   } catch (NoSuchFieldException ex) {
              Logger.getLogger(myAccessor.class.getName()).log(Level.SEVERE,
        null, ex);
   } catch (SecurityException ex) {
              Logger.getLogger(myAccessor.class.getName()).log(Level.SEVERE,
        null, ex);
   }
  }
}
I hope this elaborate on how to make a private field accessible to an outsider class. This is the case with private methods as well. You can use Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method to access the declared method(s), passing the method name as parameter just like the field example.
Method method = className.class.getDeclaredMethod("privateMethodName", null);

No comments:

Post a Comment