gpt4 book ai didi

java - 局部变量与 setter 在函数中使用泛型

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:03:57 26 4
gpt4 key购买 nike

我有一个 ITransportable 接口(interface),它强制实现它的类有两种方法,一种用于基于“this”生成对象,另一种用于从对象加载“this”。事实上,我正在使用“transports”对象向用户隐藏底层类,因此每个“可传输”类,在本例中为“ItemDetalle”,都有一个相应的传输类。 GenericTransport 类实现了我用来使代码更具可读性的一些泛型方法,并且所有传输类都派生自它。

public interface ITransportable<T> { 
public T getTransport();
public <U extends ITransportable<T>> U loadFromTransport(T transport);
}

public class GenericTransport {
[...]
public static <T extends ITransportable<U>,U extends GenericTransport> T loadFromTransport(U transport) {
try {
Method loadFromTransport=transport.getClass().getMethod("loadFromTransport");
T result = (T) loadFromTransport.invoke(transport);
return result;
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(GenericTransport.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

public static <T,U extends GenericTransport> LinkedList<T> loadFromTransport(List<U> list) {
if (list==null) return null;
LinkedList<T> ll=new LinkedList<>();
for (U element : list) ll.add((T) GenericTransport.loadFromTransport(element));
return ll;
}

}

这里有两个“孪生”类,ItemDetalle 类和 ItemDetalleTransport

public ItemDetalleTransport extends GenericTransport {
[...]
}

public class ItemDetalle implements ITransportable<ItemDetalleTransport> {
public ItemDetalleTransport getTransport() {
[...]
}
public void loadFromTransport(ItemDetalleTransport t) {
[...]
}
}

还有一个我用来做实验的类:

public class otherClass {
protected LinkedList<ItemDetalle> det
public void setDet(LinkedList<ItemDetalle> det) {
this.det=det;
}
[...]
public void test1(ItemDetalleTransport t) {
ItemDetalle det = GenericTransport.loadFromTransport(t);
}
public void test2(LinkedList<ItemDetalleTransport> t) {
LinkedList<ItemDetalle> localDet = GenericTransport.loadFromTransport(t);
this.setDet(localDet);
}
public void test3(LinkedList<ItemDetalleTransport> t) {
this.det = GenericTransport.loadFromTransport(t);
}
public void test4(LinkedList<ItemDetalleTransport> t) {
this.setDet(GenericTransport.loadFromTransport(t));
}
[...]
}

函数“test4”不起作用,声称对象的 LinkedList 不能转换为 ItemDetalle 的 LinkedList。我知道这不是一个很大的问题,但我很好奇,有人可以解释为什么吗?

谢谢!

最佳答案

在 Java 中,泛型是不变的,我将举例说明。

假设你有一个类 Parent和另一类 Child延伸Parent .泛型不变意味着 List<Child>不会被视为 List<Parent>不像数组( Child[] arr instanceof Parent[] )。

泛型不变的原因是它是通过删除实现的——这意味着它们只在编译时强制执行它们的类型约束并在运行时丢弃它们的类型信息(同样,与数组不同)。由于泛型无法在运行时强制执行其类型,并且为了安全使用 - 泛型被设为不变。

附录:由于评论下面的讨论,阅读thisthis告诉我们数组是协变的,作为类型安全和使程序更具多态性的可能性之间的权衡。当引入泛型时不需要这种权衡,因为随之而来的是通配符,可以表达协变性。非常感谢@user3580294!

关于java - 局部变量与 setter 在函数中使用泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24590670/

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