2017-06-09 24 views
1
泛型

它總是抱怨有:編譯器是不滿我在Java中

The method add(Matrix<T>) in the type List<Matrix<T>> is not applicable for the arguments (Matrix<String>) 

在提取類線:

matrixList.add(new Matrix<String>(attributes)); 

似乎有定義在我的仿製藥的問題這三類。有沒有簡單的方法來解決這個問題?嘗試了不同的方式,無法弄清楚。

public class Test { 

    public static void main(String[] args) { 

     Extractor<String> extractor = new Extractor<>(); 
     extractor.extract(); 
    } 
} 

class Extractor<T> { 

    private List<Matrix<T>> matrixList; 

    public Extractor() { 
     this.matrixList = new ArrayList<>(); 
    } 

    public void extract() { 
     List<Attribute<String>> attributes = new ArrayList<>(); 

     attributes.add(new Attribute<String>("Test 1")); 
     attributes.add(new Attribute<String>("Test 2")); 

     // !!!! The compiler is complaining here! 
     matrixList.add(new Matrix<String>(attributes)); 
    } 

    public List<Matrix<T>> getList() { 
     return matrixList; 
    } 
} 

class Matrix<T> { 

    private List<Attribute<T>> attributes; 

    public Matrix(List<Attribute<T>> attributes) { 
     this.attributes = attributes; 
    } 

    public List<Attribute<T>> getAttributes() { 
     return attributes; 
    } 
} 

class Attribute<T> { 
    private T attribute; 
    public Attribute(T attr) { 
     attribute = attr; 
    } 

    public T getAttr() { 
     return attribute; 
    } 
} 

回答

1

你不能把Matrix<String>列出的Matrix<T>T在這裏可以是任何類型)。如果Extractor僅適用於String類型的Matrix,請從中刪除類型參數,並將matrixList類型設置爲List<Matrix<String>>

+0

我不這麼認爲,在找到這樣的障礙簡單的插圖。 T可能是String或其他類型。在這個課程中,他可以在這裏爲Matrix 使用Matrix ,他可以在任何地方使用Matrix 作爲任何類型。 – htpvl

+0

@ kimdung這是完全錯誤的。你真的瞭解泛型要解決什麼問題嗎? –

+0

@kimdung在這種情況下,提取方法應該返回'Matrix '而不是將其添加到類型爲'T'的專用字段。 – fRoStBiT

5

你的代碼根本沒有意義。你正在製作Extractor等通用,這意味着你希望它適用於不同類型。

但是,在Extractor.extract()方法中,您將專門創建一個MatrixString並將其放入您的List<Matrix<T>> matrixList

如果你的代碼只適用於字符串,那麼你不應該使它通用。只要讓List<Matrix<String>> matrixList

給它一個想法:如果現在你正在創建一個Extractor<Integer> intExtractor,並且調用intExtractor.extract(),那麼你的代碼如何工作是合理的?

或者,進一步擦亮你的設計,使其:

interface Extractor<T> { 
    public List<Matrix<T>> extract(); 
} 

class DummyStringMatrixExtractor implements Extractor<String> { 

    // useless now, can be put in extract() 
    private List<Matrix<T>> matrixList; 

    public Extractor() { 
     this.matrixList = new ArrayList<>(); 
    } 

    @Override 
    public List<Matrix<String>> extract() { 
     List<Attribute<String>> attributes = new ArrayList<>(); 

     attributes.add(new Attribute<String>("Test 1")); 
     attributes.add(new Attribute<String>("Test 2")); 

     matrixList.add(new Matrix<String>(attributes)); 

     return matrixList; 
    } 

    // useless now 
    public List<Matrix<T>> getList() { 
     return matrixList; 
    } 
} 
+0

措辭巧妙Adrian –

+0

當然不僅適用於String。在這個提取器中它必須使用String,並且我有其他的提取器(從抽象提取器繼承),它可以與其他類型的對象一起工作。這就是爲什麼我想使用T型。 – user697911

+0

@ user697911這就是爲什麼我說它沒有任何意義:「這個提取器」必須與字符串一起工作,這意味着它不是用於不同類型的通用提取器。請再次檢查我的建議設計修訂,以確保您明白我的意思。 –

0

一個簡單的解決方案是使用matrixList.add((Matrix<T>) new Matrix<String>(attributes));代替。

該代碼強加了泛型非常普遍的投射問題。

代碼matrixList.add(new Matrix<String>(attributes))提出的方法意味着要在矩陣元素添加到容器matrixList其定義爲包含通用模板類型。

您可以將文檔over here

+0

它實際上有一個警告,未經檢查的強制轉換。這是好的做法嗎?將具體類型轉換爲泛型類型。如果這可行,那麼解決我的障礙可能是最容易的。 – user697911

+0

這只是一個檢查未經檢查的演員。您可以通過@SuppressWarnings(「unchecked」)取消未經檢查的警告。這是完全安全的,當然這不是一個壞習慣。 –