我知道这是一件非常罕见的事情,但是在我将一个名为“progress”的函数重构为“setProgress”之后,它今天发生在我身上。我有这个代码创建一个SwingWorker的匿名子类型的对象,并在其“doInBackground”方法中我有另一个函数调用我自己的自定义类型,也是匿名类型。事实证明,这两种类型都具有完全相同的功能,称为“setProgress”。注意:SwingWorkerEx只是SwingWorker的自定义子类型。
new SwingWorkerEx<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
final SwingWorkerEx self = this;
lazyNode.loadForce(_dao, new ProgressListener() {
@Override
public void setProgress(@Nullable ProgressOperation operation, int percent) {
setProgress(percent);
}
});
return null;
}
我得到的错误是:
...中的setProgress(ProgressOperation,int)不能应用于(int)
Java显然认为我正在尝试引用最内层类的setProgress方法,并认为我的参数错误。幸运的是,功能签名不匹配,或者我以后会有无限的递归来处理!我试图消除歧义,但不能。我甚至尝试过这个解决方案:How to refer to enclosing anonymous class instance in Java?,执行以下操作:
protected Void doInBackground() throws Exception {
final SwingWorkerEx self = this;
和
@Override
public void setProgress(@Nullable ProgressOperation operation, int percent) {
self.setProgress(percent);
}
但是访问修饰符的微妙之处让我感到震惊。特别是,Java抱怨道:
'setProgress(int)'在'javax.swing.SwingWorker'中保护了访问权限
我只是给其中一个类命名,但我想知道在Java中理论上是否可以解决这个问题?如果没有,这是一个有趣的限制。
我想到的另一件事是将SwingWorker的函数提取为Function类型,然后将此函数传递给嵌套的匿名类,但是它是void类型的!使其成为Void(资本V)只是一种解决方法,而不是解决方案。无论如何,名义上的IMO定义是更好的解决方案。
另一件不起作用的事情是覆盖了匿名SwingWorkerEx子类型中的setProgress函数:
@Override
public void setProgress(int percent){super.setProgress(percent);}
这是因为该函数在SwingWorker中是最终的。
答案 0 :(得分:0)
对于面临这一挑战的任何人来说,这是一种解决方法。我不会接受这个,因为它不是解决方案。也许没有解决方案。
在SwingWorkerEx的匿名子类中,定义此函数:
public void setProgressSuper(int percent){super.setProgress(percent);}
然后在doInBackground函数中的ProgressListener的匿名实现中调用它:
@Override
public void setProgress(@Nullable ProgressOperation operation, int percent) {
setProgressSuper(percent);
}
});
全部放在一起:
new SwingWorkerEx<Void, Void>() {
//Need this as a workaround to accessing the protected function in the anonymous ProgressListener class below
public void setProgressSuper(int percent){super.setProgress(percent);}
@Override
protected Void doInBackground() throws Exception {
lazyNode.loadForce(_dao, new ProgressListener() {
@Override
public void setProgress(@Nullable ProgressOperation operation, int percent) {
setProgressSuper(percent);
}
});
return null;
}
...