原始使用参数化 class 'ABC'
Raw use of parameterized class 'ABC'
我有以下界面:
public interface AsynchronousJobRunner<T extends AsynchronousJob> extends Runnable {
public void kill();
public void addJobExecutionListener(JobExecutionListener listener);
public void removeJobExecutionListener(JobExecutionListener listener);
public AsynchronousJobRunner withJob(T job);
}
AsynchronousJob
是一个抽象 class ,可以使用以下抽象方法扩展以表示其他作业:
public abstract class AsynchronousJob implements JSONSerializable, HasId {...}
/**
* Returns the class of the {@link AsynchronousJobRunner} that runs this type of job.
* @return The appropriate class of the job runner for this class.
*/
public abstract Class<? extends AsynchronousJobRunner> jobRunnerClass();
我还有以下 ExportJob
扩展基础 class 并具有以下签名和方法:
public class ExportJobRunner extends BaseJobRunner<ExportJob> { ...}
@Override
public Class<? extends AsynchronousJobRunner> jobRunnerClass() {
return ExportJobRunner.class;
}
两种 jobRunnerClass()
方法都有 Raw use of parameterized class 'AsynchronousJobRunner'
警告。
使警告消失的简单解决方案是:
public abstract Class<? extends AsynchronousJobRunner<?>> jobRunnerClass();
@Override
public Class<? extends AsynchronousJobRunner<?> jobRunnerClass() {
return ExportJobRunner.class;
}
但是正确的解决方案是什么 why/how?
编辑:
我最终只是将界面代码更改为:
public interface AsynchronousJobRunner<T extends AsynchronousJob<T>> extends Runnable {
void kill();
void addJobExecutionListener(JobExecutionListener listener);
void removeJobExecutionListener(JobExecutionListener listener);
AsynchronousJobRunner<T> withJob(T job);
}
更改为 AsynchronousJob
class:
public abstract class AsynchronousJob<T> implements JSONSerializable, HasId { ...
/**
* Returns the class of the {@link AsynchronousJobRunner} that runs this type of job.
* @return The appropriate class of the job runner for this class.
*/
public abstract Class<? extends AsynchronousJobRunner<? extends AsynchronousJob<T>> jobRunnerClass();
}
ExportJob
class:
public public class ExportJob extends AsynchronousJob<ExportJob> {...
@Override
public Class<? extends AsynchronousJobRunner<? extends AsynchronousJob<ExportJob>>> jobRunnerClass() {
return ExportJobRunner.class;
}
}
而ExportJobRunner
class保持不变。
我还忘了说,由于作业被序列化到数据库,所以正在进行一些注入魔法:
/**
* Instantiates an {@link AsynchronousJobRunner} instance for the provided job.
* <p>
* In order for the creation of the runner to succeed, the {@link AsynchronousJob#jobRunnerClass()}
* method of the job must specify the appropriate class for its runner.
*
* @param job job to create runner for
* @return job runner configured for the specified {@code job} parameter
*/
private <T extends AsynchronousJob<T>> AsynchronousJobRunner<T> createJobRunner(T job) {
return ((AsynchronousJobRunner<T>)injector.getInstance(job.jobRunnerClass())).withJob(job);
}
我接受了@Andrew Vershinin 的回答,因为他让我走上了正确的思路。
我认为,您可以使用 AsynchronousJob
的递归声明:
public abstract class AsynchronousJob<T extends AsynchronousJob<T>>
implements JSONSerializable, HasId {
public abstract Class<? extends AsynchronousJobRunner<T>> jobRunnerClass();
//...
}
不要忘记相应地更新 AsynchronousJobRunner
定义:
public interface AsynchronousJobRunner<T extends AsynchronousJob<T>> //...
然后,在你的工作 class 中,你可以在 return 类型中使用 class 本身:
public class ExportJob extends AsynchronousJob<ExportJob> {
@Override
public Class<? extends AsynchronousJobRunner<ExportJob>> jobRunnerClass() {
return ExportJobRunner.class;
}
}
这样可以确保类型一致性:T
returns 运行ner 类型的工作,运行 这种类型的工作 - 你无法确保这一点在 jobRunnerClass
签名中使用 ? extends AsynchronousJob
,因为你可以 return 任何 运行ner 类型并且它会编译。
我有以下界面:
public interface AsynchronousJobRunner<T extends AsynchronousJob> extends Runnable {
public void kill();
public void addJobExecutionListener(JobExecutionListener listener);
public void removeJobExecutionListener(JobExecutionListener listener);
public AsynchronousJobRunner withJob(T job);
}
AsynchronousJob
是一个抽象 class ,可以使用以下抽象方法扩展以表示其他作业:
public abstract class AsynchronousJob implements JSONSerializable, HasId {...}
/**
* Returns the class of the {@link AsynchronousJobRunner} that runs this type of job.
* @return The appropriate class of the job runner for this class.
*/
public abstract Class<? extends AsynchronousJobRunner> jobRunnerClass();
我还有以下 ExportJob
扩展基础 class 并具有以下签名和方法:
public class ExportJobRunner extends BaseJobRunner<ExportJob> { ...}
@Override
public Class<? extends AsynchronousJobRunner> jobRunnerClass() {
return ExportJobRunner.class;
}
两种 jobRunnerClass()
方法都有 Raw use of parameterized class 'AsynchronousJobRunner'
警告。
使警告消失的简单解决方案是:
public abstract Class<? extends AsynchronousJobRunner<?>> jobRunnerClass();
@Override
public Class<? extends AsynchronousJobRunner<?> jobRunnerClass() {
return ExportJobRunner.class;
}
但是正确的解决方案是什么 why/how?
编辑:
我最终只是将界面代码更改为:
public interface AsynchronousJobRunner<T extends AsynchronousJob<T>> extends Runnable {
void kill();
void addJobExecutionListener(JobExecutionListener listener);
void removeJobExecutionListener(JobExecutionListener listener);
AsynchronousJobRunner<T> withJob(T job);
}
更改为 AsynchronousJob
class:
public abstract class AsynchronousJob<T> implements JSONSerializable, HasId { ...
/**
* Returns the class of the {@link AsynchronousJobRunner} that runs this type of job.
* @return The appropriate class of the job runner for this class.
*/
public abstract Class<? extends AsynchronousJobRunner<? extends AsynchronousJob<T>> jobRunnerClass();
}
ExportJob
class:
public public class ExportJob extends AsynchronousJob<ExportJob> {...
@Override
public Class<? extends AsynchronousJobRunner<? extends AsynchronousJob<ExportJob>>> jobRunnerClass() {
return ExportJobRunner.class;
}
}
而ExportJobRunner
class保持不变。
我还忘了说,由于作业被序列化到数据库,所以正在进行一些注入魔法:
/**
* Instantiates an {@link AsynchronousJobRunner} instance for the provided job.
* <p>
* In order for the creation of the runner to succeed, the {@link AsynchronousJob#jobRunnerClass()}
* method of the job must specify the appropriate class for its runner.
*
* @param job job to create runner for
* @return job runner configured for the specified {@code job} parameter
*/
private <T extends AsynchronousJob<T>> AsynchronousJobRunner<T> createJobRunner(T job) {
return ((AsynchronousJobRunner<T>)injector.getInstance(job.jobRunnerClass())).withJob(job);
}
我接受了@Andrew Vershinin 的回答,因为他让我走上了正确的思路。
我认为,您可以使用 AsynchronousJob
的递归声明:
public abstract class AsynchronousJob<T extends AsynchronousJob<T>>
implements JSONSerializable, HasId {
public abstract Class<? extends AsynchronousJobRunner<T>> jobRunnerClass();
//...
}
不要忘记相应地更新 AsynchronousJobRunner
定义:
public interface AsynchronousJobRunner<T extends AsynchronousJob<T>> //...
然后,在你的工作 class 中,你可以在 return 类型中使用 class 本身:
public class ExportJob extends AsynchronousJob<ExportJob> {
@Override
public Class<? extends AsynchronousJobRunner<ExportJob>> jobRunnerClass() {
return ExportJobRunner.class;
}
}
这样可以确保类型一致性:T
returns 运行ner 类型的工作,运行 这种类型的工作 - 你无法确保这一点在 jobRunnerClass
签名中使用 ? extends AsynchronousJob
,因为你可以 return 任何 运行ner 类型并且它会编译。