我已經嘗試了以下代碼的許多不同變體,但找不到任何不依賴不安全強制轉換或導致另一個其他編譯器警告的解決方案。我相信這個目標是可能的,但也許不是?
簡單地說,目標是我派生了彼此相關且具有不變關系的型別,可以通過泛型方法強制執行。
AlphaTask總是回傳AlphaTaskResult。
AlphaTask是 的具體實作ITask<T>,其中T是String。
AlphaTaskResult擴展了 的基類TaskResult<T>,這里又T是String。
一切都檢查出來,直到撰寫一個通用方法,該方法接受任何Task并回傳相應的TaskResult型別。
錯誤是:
Required type: List<U>
Provided: List<TaskResult<T>>
no instance(s) of type variable(s) exist so that TaskResult<T> conforms to U inference variable T has incompatible bounds: equality constraints: U lower bounds: TaskResult<T>
package com.adobe.panpipe;
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
interface ITask<T>{
TaskResult<T> make();
}
class TaskResult<T>{
T value;
}
class AlphaTaskResult extends TaskResult<String> {
AlphaTaskResult(String value){
this.value = value;
}
}
class BetaTaskResult extends TaskResult<Integer> {
BetaTaskResult(Integer value){
this.value = value;
}
}
class AlphaTask implements ITask<String> {
public AlphaTaskResult make(){
return new AlphaTaskResult("alphaTask");
}
}
class BetaTask implements ITask<Integer> {
public BetaTaskResult make(){
return new BetaTaskResult(9001);
}
}
public class Main <T>{
public static <T, U extends TaskResult<T>, V extends ITask<T>> List<U> run(List<V> tasks){
List<U> results = tasks
.stream()
.map(ITask::make)
.collect(Collectors.toList());
return results;
}
public static void main(String[] args) {
List<AlphaTaskResult> alphaResults = run(Arrays.asList(new AlphaTask(), new AlphaTask()));
List<BetaTaskResult> betaResults = run(Arrays.asList(new BetaTask(), new BetaTask()));
}
}
uj5u.com熱心網友回復:
ITask和之間沒有聯系TaskResult。當然,任務實作會覆寫make它們各自的回傳型別,但是不能在run方法的宣告中使用此資訊。
您可以通過向以下位置添加額外的型別引數來建立連接ITask:
interface ITask<T, TResult extends TaskResult<T>>{
TResult make();
}
class TaskResult<T>{
T value;
}
更改任務實作并run相應地:
class AlphaTask implements ITask<String, AlphaTaskResult> {
public AlphaTaskResult make(){
return new AlphaTaskResult("alphaTask");
}
}
class BetaTask implements ITask<Integer, BetaTaskResult> {
public BetaTaskResult make(){
return new BetaTaskResult(9001);
}
}
public class Main { // Main doesn't need a type parameter
public static <T, U extends TaskResult<T>, V extends ITask<T, U>> List<U> run(List<V> tasks){
List<U> results = tasks
.stream()
.map(ITask::make)
.collect(Collectors.toList());
return results;
}
public static void main(String[] args) {
List<AlphaTaskResult> alphaResults = run(Arrays.asList(new AlphaTask(), new AlphaTask()));
List<BetaTaskResult> betaResults = run(Arrays.asList(new BetaTask(), new BetaTask()));
}
}
uj5u.com熱心網友回復:
只需將R extends TaskResult<T>結果的型別添加到ITask任務的型別中即可。以下編譯得很好:
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
interface ITask<T, R extends TaskResult<T>>{
R make();
}
class TaskResult<T>{
T value;
}
class AlphaTaskResult extends TaskResult<String> {
AlphaTaskResult(String value){
this.value = value;
}
}
class BetaTaskResult extends TaskResult<Integer> {
BetaTaskResult(Integer value){
this.value = value;
}
}
class AlphaTask implements ITask<String, AlphaTaskResult> {
public AlphaTaskResult make(){
return new AlphaTaskResult("alphaTask");
}
}
class BetaTask implements ITask<Integer, BetaTaskResult> {
public BetaTaskResult make(){
return new BetaTaskResult(9001);
}
}
public class Main <T>{
public static <T, R extends TaskResult<T>> List<R> run(List<ITask<T, R>> tasks){
List<R> results = tasks
.stream()
.map(ITask::make)
.collect(Collectors.toList());
return results;
}
public static void main(String[] args) {
List<AlphaTaskResult> alphaResults = run(Arrays.asList(new AlphaTask(), new AlphaTask()));
List<BetaTaskResult> betaResults = run(Arrays.asList(new BetaTask(), new BetaTask()));
}
}
您的版本無法編譯的原因是結果的確切型別未包含在任務的型別中,并且由于 Java 中沒有型別細化,因此U無法推斷出型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/519741.html
標籤:爪哇仿制药遗产界面
