gpt4 book ai didi

Java 编译器不同意泛型方法调用的安全性

转载 作者:行者123 更新时间:2023-11-30 08:07:51 25 4
gpt4 key购买 nike

我正在研究表示 SQL 结果集的一些抽象集,并编写了以下方法:

public interface Column<T>{
//some methods
}

public class SqlRowExtractor{

public void doExtraction(){
Collection<Column<?>> cols = getColumns(); //Returns the collection of Column<T>.
//A particular result set may contain,
//for instance 2 Column<Date>,
//1 Column<Integer> and so fotrh

for(Column<?> c : cols){
put(c, get(c)); //1 <-------------------- HERE
//Compile-error
}
//other staff
}

public <T> void put(Column<T> c, T o){
//put the extracted value in another place
}

public <T> T get(Column<T> c) throws SQLException{
//extract the value of the row for the Column<T> c
}
}

我在 //1 处遇到编译错误,尽管 putget 方法的签名非常清楚,没有放置不适当值的方法。如何以类型安全的方式修复错误?错误信息:

The method put(Column<T>, T) is not applicable for the arguments 
(Column<capture#3-of ?>, capture#4-of ?)

最佳答案

这不会编译,因为编译器不理解 get 调用的通配符类型与 中通配符类型的使用是同一类型code>set 调用,即使这些方法用于同一对象。

可以通过引入一个带类型参数的util方法来解决。这样,通配符类型只使用一次,并且在方法内部类型参数将有一个具体类型,编译器可以理解它是同一个在多个地方使用的类型。

在使用它的每个单独的地方分配给通配符类型的具体类型称为通配符类型的捕获,并给它起一个像capture#3-of ? 由编译器执行。

以下编译:

private <T> void getPut(Column<T> c) throws SQLException {
// Compiles because the type's capture, which in non-wildcard, has been bound to T
put(c, get(c));
}

public void doExtraction() throws SQLException {
Collection<Column<?>> cols = getColumns();
for(Column<?> c : cols) {
// Compiles because wild-card type of c is only used once
getPut(c);
}
}

example of capturing conversion in the JLS 中使用了相同的技术.

关于Java 编译器不同意泛型方法调用的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33450515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com