num*_*ger 13 java reflection polymorphism access-modifiers
我知道我可以使用反射来调用私有方法,并获取或设置一个私有变量的值,但我要重写的方法.
public class SuperClass {
public void printInt() {
System.out.println("I am " + getClass() + ". The int is " + getInt());
}
private int getInt() {
return 1;
}
}
public class SubClass extends SuperClass {
public static void main(String[] args) {
(new SubClass()).printInt();
}
public int getInt() {
return 2;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要 打印输出的main方法,但它打印出来.我听说这可以通过反思完成,但我无法弄清楚如何.如果没有反思,有没有人知道另一种方式呢?(除了保护,复制和粘贴方法之外.)如果实际覆盖私有方法是不可能的,有没有办法在它上面放置某种类型的触发器,它将调用我的子类中的方法之前或私有方法执行后?SubClass21SuperClass.getInt()printInt()SubClass
eri*_*son 19
您不能覆盖私有方法,因为没有其他类(包括派生类)可以告诉它存在.这是私人的.
私有方法是隐含的final.
在相关的注释中,子类可以声明一个与private超类中的字段或方法同名的字段或方法,因为从子类的角度来看,这些成员不存在.这些成员之间没有特殊关系.
tru*_*ity 14
私有方法不会被继承,也不能以任何方式覆盖.无论谁告诉你,你都可以用反思去做,或者说谎或者谈论其他事情.
但是,您可以访问getInt任何子类正在调用的私有方法,printInt如下所示:
public void printInt() throws Exception {
Class<? extends SuperClass> clazz = getClass();
System.out.println("I am " + clazz + ". The int is " +
clazz.getMethod("getInt").invoke(this) );
}
Run Code Online (Sandbox Code Playgroud)
这将具有getInt从超类调用子类' 方法'的效果printInt.当然,如果子类没有声明a ,现在这将失败getInt,所以你必须添加一个检查以便能够处理不试图"覆盖"私有方法的"普通"子类:
public void printInt() throws Exception {
Class<? extends SuperClass> clazz = getClass();
// Use superclass method by default
Method theGetInt = SuperClass.class.getDeclaredMethod("getInt");
// Look for a subclass method
Class<?> classWithGetInt = clazz;
OUTER: while( classWithGetInt != SuperClass.class ){
for( Method method : classWithGetInt.getDeclaredMethods() )
if( method.getName().equals("getInt") && method.getParameterTypes().length == 0 ){
theGetInt = method;
break OUTER;
}
// Check superclass if not found
classWithGetInt = classWithGetInt.getSuperclass();
}
System.out.println("I am " + classWithGetInt + ". The int is " + theGetInt.invoke(this) );
}
Run Code Online (Sandbox Code Playgroud)
您仍然可以更改超代码,使这项工作,因为你必须改变超类的代码,你应该只改变访问修饰符getInt来protected的,而不是做反射下锅变通.
Jon*_*eet 14
不,你不能.您可以使用外部类中的代码可以访问嵌套类的私有成员这一事实来构建一个看起来应该能够执行此操作的程序.但是,私有方法实际上仍然无法被覆盖.例:
public class Test {
public static class Superclass {
private void foo() {
System.out.println("Superclass.foo");
}
}
public static class Subclass extends Superclass {
private void foo() {
System.out.println("Subclass.foo");
// Looks like it shouldn't work, but does...
super.foo();
}
}
public static void main(String[] args) throws Exception {
Superclass x = new Subclass();
// Only calls Superclass.foo...
x.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于这将是唯一可以覆盖私有方法的情况,因此不支持它并不是很大的损失.
如果您想要更改超类私有成员的行为,基本上您的设计就会被破坏.
我无法通过反射来做到这一点,但我已经找到了通过仪器来实现这一目标的方法.我在Dhruba Bandopadhyay的博客上建议使用ASM .如果您有兴趣,可以查看我的代码(这里发布的内容太多了).