18
public class A{
    private int getC(){
        return 0;
    }
}

public class B extends A{
    public static void main(String args[]){
        B = new B();
        //here I need to invoke getC()
    }
}

Can you please tell me if it is possible to do sush thing via reflection in java?

dmreshet
  • 1,496
  • 3
  • 18
  • 28
  • 1
    Please don't use parent/child analogy for inheritance. A `B` object *is an* `A` object. Are you your father? – aioobe Jan 18 '13 at 11:45
  • 4
    @aioobe `B` is a child of `A` in the inheritance hierarchy. It's legit. – Marko Topolnik Jan 18 '13 at 11:49
  • I still think it's a bad analogy, especially when used as "invoke parent private method from child". I would definitely use "method in superclass from subclass". – aioobe Jan 18 '13 at 11:51
  • 2
    @aioobe agree it's not technically correct, but can we agree that the parent/child analogy vis-a-vis class inheritance is so well-established that it has become a de-facto synonym with superclass/subclass. The literature on object oriented programming is littered with it. – pap Jan 18 '13 at 14:07
  • 2
    Nope. Can't say I can agree with you on that. I only see it written by people that are either new to the concept of inheritance, or by people that simply never reflected over the fact that parent/child does not have an *"is a"*-relationship. You can always get around it easily by using a different (more accurate) terminology and I don't think it is well-established. – aioobe Jan 18 '13 at 14:36

5 Answers5

21
class A{
    
    private void a(){
        System.out.println("private of A called");
    }
}

class B extends A{
    
    public void callAa(){
        try {
            System.out.println(Arrays.toString(getClass().getSuperclass().getMethods()));
            Method m = getClass().getSuperclass().getDeclaredMethod("a", new Class<?>[]{});
            m.setAccessible(true);
            m.invoke(this, (Object[])null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

EDIT: This is quiet an old post but adding a few nuggets of advice

Reconsider your design

Calling private method of parent, though possible through Reflection, but should not be done. Calling private methods on parent might leave the class in invalid state and may lead to unexpected behaviors.

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
11

You can do it using reflection, but unless there is a very good reason to do so, you should first reconsider your design.

The code below prints 123, even when called from outside A.

public static void main(String[] args) throws Exception {
    Method m = A.class.getDeclaredMethod("getC");
    m.setAccessible(true); //bypasses the private modifier
    int i = (Integer) m.invoke(new A());
    System.out.println("i = " + i); //prints 123
}

public static class A {

    private int getC() {
        return 123;
    }
}
assylias
  • 321,522
  • 82
  • 660
  • 783
4

You should declare getc protected. That's exactly what it's for.

As for reflection: Yes, it is possible. You'd have to call setAccessible on the method object though. And it's bad style... ;-)

Axel
  • 13,939
  • 5
  • 50
  • 79
  • I can not change getC() to to protected, cause it is in JDK :) – dmreshet Jan 18 '13 at 11:51
  • 1
    Then be aware that your code might not work on other JDK versions than the one you are using in development. And even on the one you work with, it might fail if your application runs with a security manager (like in applets). You should definitely look for another way. – Axel Jan 18 '13 at 12:04
  • Read about it here: http://java.dzone.com/articles/reflection-and-missing-0 – Axel Jan 18 '13 at 12:06
3

getDeclaredMethod will only return the private methods in the current class not the inherited methods. To achieve it you need to navigate the inheritance graph via the getSuperclass method. Here is a code snippet that does it

  private Method getPrivateMethod(Object currentObject) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  Class<?> currentClass = currentObject.getClass();
  Method method = null;
  while (currentClass != null && method == null) {
      try {
          method = currentClass.getDeclaredMethod("getC");
      } catch (NoSuchMethodException nsme) {
          // method not present - try super class
          currentClass = currentClass.getSuperclass();
      }
  }
  if (method != null) {
      method.setAccessible(true);
      return method;
  } else {
      throw new NoSuchMethodException();
  }

}

0

you can try like this using reflection:

    Method getCMethod = A.class.getDeclaredMethod("getC");
    getCMethod.setAccessible(true);
    getCMethod.invoke(new A());
vishal_aim
  • 7,636
  • 1
  • 20
  • 23