【问题标题】:How to invoke parent private method from child? [duplicate]如何从孩子调用父私有方法? [复制]
【发布时间】:2013-01-18 11:39:54
【问题描述】:
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()
    }
}

你能告诉我是否可以通过 java 中的反射来做 sush 事情?

【问题讨论】:

  • 请不要使用父/子类比继承。 B 对象 A 对象。你是你父亲吗?
  • @aioobe B 是继承层次结构中A 的子级。这是合法的。
  • 我仍然认为这是一个不好的类比,尤其是当用作“从孩子调用父私有方法”时。我肯定会使用“子类中的超类方法”。
  • @aioobe 同意这在技术上是不正确的,但是我们是否可以同意父/子类与类继承的类比是如此完善,以至于它已成为超类/ 的事实上的同义词子类。面向对象编程的文献中充斥着它。
  • 不。不能说我同意你的看法。我只看到它是由对继承概念不熟悉的人编写的,或者是那些根本没有考虑过父/子没有“is a”-关系这一事实的人写的。您总是可以通过使用不同(更准确)的术语轻松绕过它,但我认为它并不成熟。

标签: java reflection


【解决方案1】:
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();
        }
    }
}

编辑: 这是一篇安静的旧帖子,但添加了一些建议

重新考虑您的设计

调用父级的私有方法,虽然可以通过反射,但不应该这样做。在父类上调用私有方法可能会使类处于无效状态并可能导致意外行为。

【讨论】:

  • 他为什么不能直接打电话给this.getC()
【解决方案2】:

您可以使用反射来做到这一点,但除非有充分的理由这样做,否则您应该首先重新考虑您的设计。

下面的代码打印 123,即使是从外部 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;
    }
}

【讨论】:

  • 请注意,m.invoke(new B()); 也可以。
  • 问题是我不能创建A的实例。A和B有共同的状态。
  • @user1545453 正如我上面评论的那样,您可以使用 B 的实例,它也可以工作。
【解决方案3】:

您应该声明 getc protected。这正是它的用途。

至于反思:是的,这是可能的。不过,您必须在方法对象上调用 setAccessible。而且风格很糟糕... ;-)

【讨论】:

  • 我无法将 getC() 更改为受保护,因为它在 JDK 中 :)
  • 那么请注意,除了您在开发中使用的版本之外,您的代码可能无法在其他 JDK 版本上运行。即使在您使用的那个上,如果您的应用程序使用安全管理器(如在小程序中)运行,它也可能会失败。你绝对应该寻找另一种方式。
【解决方案4】:

getDeclaredMethod 只会返回当前类中的私有方法,而不是继承的方法。要实现它,您需要通过 getSuperclass 方法导航继承图。这是一个代码sn-p

  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();
  }

}

【讨论】:

    【解决方案5】:

    您可以尝试使用反射:

        Method getCMethod = A.class.getDeclaredMethod("getC");
        getCMethod.setAccessible(true);
        getCMethod.invoke(new A());
    

    【讨论】:

    • getCMethod.invoke(null); 会抛出一个 NPE。
    • 谢谢,已更正。那是静态方法
    猜你喜欢
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多