有没有办法基本上“覆盖”最终变量?

时间:2013-08-09 15:12:40

标签: java inheritance override

我知道你不能覆盖变量,但有没有办法在下面“覆盖”最后的工人变量?

public class ClassA {
   final protected CustomClass worker;

   public doComplicatedWork() {
        ....
        worker.doSomething();
        ....
   }
}

基本上我想做的就是扩展CustomClass并让ClassA正常地完成所有工作,但worker将是我的扩展CustomClassClassA和原始CustomClass都在jar中,因此我不想参与修改它们。有没有办法做到这一点?

6 个答案:

答案 0 :(得分:1)

听起来你不需要这样做。假设您将worker作为构造函数参数传递给ClassA,因此只需构建您的工作者,并将其传递给ClassA。您的问题中没有任何内容使您觉得需要削弱final声明。

答案 1 :(得分:0)

如果构造函数没有接收CustomClass worker作为参数,则可以使用反射来执行此操作。

代码示例:

class ClassA {
    final protected CustomClass worker = null;

    public void doComplicatedWork() {
    }

    public void printWorker(){
        System.out.println(worker); //testing method
    }
}

class CustomClass {
    ...
}

class NewCustomClass extends CustomClass{
    //Your new CustomClass
}

使用反思:

public static void main(String[] args) throws Exception {

    ClassA classA = new ClassA();
    Field f = classA.getClass().getDeclaredField("worker");
    f.setAccessible(true);
    f.set(classA, new NewCustomClass());
    classA.printWorker();
}

它打印:NewCustomClass@19d449fc这意味着我们覆盖了它。

答案 2 :(得分:0)

除了反思,它应该永远是最后的手段,你可以通过巧妙地设计你的访问者来模拟覆盖这个值。即:

public class SubClass extends ClassA
{
      final protected CustomClass subWorker;

      public CustomClass getWorker()
      {
          return this.subWorker;
      }
}

如果变量仍然是protected,则您知道用户无法从类外部访问它。每当他们从getWorker拨打SubClass时,您已覆盖它,它将检索subWorker而不是worker

答案 3 :(得分:0)

您可以使用反射来绕过final

  Field field = ClassA.getField("worker"));
  field.setAccessible(true);
  Field modifiers = Field.class.getDeclaredField("modifiers");
  modifiers .setAccessible(true);
  modifiers .setInt(field, field.getModifiers() & ~Modifier.FINAL);
  field.set(this, newWorker);

答案 4 :(得分:0)

我可能没有正确理解它,但是..你不能扩展ClassA,并用扩展的worker-class切换变量worker?

public class YourWorkerClass extends CustomClass 
{
     public DoSomething()
     { 
         //yourstuff
     }
}

public class YourClassA extends ClassA
{
    public YourClassA()
    {
        worker = new YourWorkerClass()
    }
}

答案 5 :(得分:0)

您可以扩展ClassA但基本上忽略现有的实现并重新实现所有外部,以便您使用等效的" worker"。