2014-09-17 3 views
2

자식 클래스의 메서드를 덮어 쓸 때 제네릭이 작동하는 방식을 잘 모르겠습니다.Java generics의 상속 된 메서드

import com.fasterxml.sort.DataReader; 

public class CSVReader<E> extends DataReader<E> 
{ 

    private final ICsvListReader reader; 

    public CSVReader(InputStream in) { 
     reader = new CsvListReader(new InputStreamReader(in), CsvPreference.STANDARD_PREFERENCE); 
    } 

    @Override 
    public E readNext() throws IOException { 
     java.util.List<String> line=reader.read(); 
     return line;//compilation error 
    } 
} 

오류

Type mismatch: cannot convert from List<String> to E CSVReader.java 

나는이 문제를 어떻게 해결합니까? genericized 클래스를 확장 할 때 일반적으로

답변

1

,뿐만 아니라 확장 된 클래스의 서명으로 제네릭 형식을 지정해야합니다 : 당신이 List, 당신은보다 구체적인 얻을 수 있습니다하려는 경우

public class CSVReader<T> extends DataReader<T> { 

    ... 
    @Override 
    public T readNext() throws IOException { 
     ... 
    } 
} 

을, 이 작업을 수행합니다

public class CSVReader<T extends List<E>> extends DataReader<T> { 
    ... 
    @Override 
    public List<E> readNext() throws IOException { 
     ... 
    } 
} 

나는 ICsvListReader를 살펴 가져다가 클래스 readNext() 다소 페이지의 구현을 만들 것입니다 genericized하지입니다 문제. read은 항상 List<String>을 반환합니다. 따라서 어떤 사람이 CSVReader 인 인스턴스를 CSVReader<List<Integer>>으로 인스턴스화하면 readNextList<String>을 반환하기 때문에 문제가 발생합니다 (힙 오염). 그러면 목록의 요소에 액세스하려고 시도 할 때 ClassCastException으로 끝납니다. 컴파일러에서 경고 할 수 있습니다 (Java 7이 있다고 생각합니다)하지만 일반 유형이 유형 지우기로 인해 런타임에 손실되기 때문에 코드가 실제로 컴파일됩니다. 따라서이 경우에 나는 정말 명시하는 것이 낫다 생각하고 대신 이렇게 :

public class CSVReader extends DataReader<List<String>> { 

    private final ICsvListReader reader; 

    ... 

    @Override 
    public List<String> readNext() throws IOException { 
     return reader.read(); //read already throws an IOException so you're good to go 
    } 
} 
0

당신은 함수 정의에서 제네릭 형식을 반환하지만 함수 자체에 목록을 반환 말한다. 다음과 같이 수정하십시오.

public <E> List<E> readNext() { 
    java.util.List<E> line= reader.read(); 
    return line; 
} 
1

서명을 일치 시키려면 서명을 일치시켜야합니다.

public class CSVReader<E extends List> extends DataReader<E> 
1

DataReader는 데이터 항목의 일부 알 수없는 유형에서 작동합니다.

public abstract class DataReader<T> { ... } 

귀하의 CSVReader 서브 클래스는 이미와 운영 데이터 항목의 구체적인 유형을 알고이 그것이 일반적인 클래스로 선언하는 이유입니다. 내가 아는 한 CSV 행을 나타내는 List<String>에서 작동하고 싶습니다. 그걸 염두에두고

, 당신은 단순히 좀 더 구체적인 클래스를 선언해야합니다

public class CSVReader extends DataReader<List<String>> { 
    @Override 
    public List<String> readNext() throws IOException { ... } 
}