在不触及源代码的情况下更改成员方法,向下转换?

时间:2014-02-18 20:00:23

标签: java oop downcast

假设我正在使用其中包含A类的第三方项目。 A级到处使用。在A类中,我对方法M1不满意。首先,我不想改变A类,其次,我需要A.M1()知道上下文中的某些内容。 (M1将由其他人调用)我的设计将是:

public MyClass {
    ContextInfo ci;

    public class B extends A {
    //@Override M1() {use ci}
    }

    //Somehow I have a stack of A, 
    //and I know this is the only places A objects will be in

    Stack<A> s = getStack();
    //Now I wanna replace the top of the stack. or I can convert all As to Bs in the stack
    A a = s.pop();
    B b = (B) a;              //here it fails
    s.push(b);
}

由于我是向下转发,我有运行时投射错误。有没有办法让编译器或JVM认识到B只能做A允许做的事情(不是严格的子类型),这样这应该不是问题?或者其他一些想法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

简单的答案是“不”。如果对象是要直接或通过继承转换为的类型的实例,则仅转换成功。使B成为A的子类,您将能够(几乎)在任何可以使用A的地方使用它。如果不是,你就不能。

这种限制有很多充分的理由,包括安全性。

如果您真的想重新定义A,如果您有权访问类路径,则可以在某种程度上这样做。将新A放在类路径中,它将首先被找到。当然,任何由于这样做而中断的都是完全属于你自己的错误,并且会有这样的情况:破坏会(不会)让你感到惊讶 - 你将无法从两个不同的来源混合A的实例。 (例如,使用多个类加载器可能会让你进入那个角落。)你展示解决方案的任何人都可能会尖叫。

但这几乎肯定是一个“x / y问题”。你已经跳到了解决方案而不是与我们讨论问题。这几乎肯定是问题的错误解决方案。我建议你退后一步,弄清楚你试图通过滥用课堂系统来达到什么目的,然后向我们寻求合法的建议。