我知道你不能覆盖变量,但有没有办法在下面“覆盖”最后的工人变量?
public class ClassA {
final protected CustomClass worker;
public doComplicatedWork() {
....
worker.doSomething();
....
}
}
基本上我想做的就是扩展CustomClass
并让ClassA
正常地完成所有工作,但worker
将是我的扩展CustomClass
。 ClassA
和原始CustomClass
都在jar中,因此我不想参与修改它们。有没有办法做到这一点?
答案 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"。