锁定老帖子 主题:关于Java泛型 与 类型推断
精华帖 (0) :: 良好帖 (3) :: 新手帖 (1) :: 隐藏帖 (12)
|
|
---|---|
作者 | 正文 |
发表时间:2012-02-15
其实我没明白楼上说的:表现的像协变,与真正协变怎么个去理解。。
不太明白你这两个概念。 |
|
返回顶楼 | |
发表时间:2012-02-15
mwei 写道 就是说java的List不支持协变,即使使用wildcard也只能使List表现的像是在协变,实际上使用wildcard后List也不是真正的协变。
其实你的疑问点还是跟use-site与declaration-site的区别有关。是,List<E>类型内在是invariant的,这是在declaration-site所提供的信息。但use-site可以任意指定这个地方所需要的variance。所以你在use-site既可以写出 List<? extends Fruit> ,也可以写出 List<? super Fruit> ,就看你需要的是什么(是producer?consumer?)。这不是表象啊真实啊啥的问题。 |
|
返回顶楼 | |
发表时间:2012-02-16
RednaxelaFX 写道 mwei 写道 就是说java的List不支持协变,即使使用wildcard也只能使List表现的像是在协变,实际上使用wildcard后List也不是真正的协变。
其实你的疑问点还是跟use-site与declaration-site的区别有关。是,List<E>类型内在是invariant的,这是在declaration-site所提供的信息。但use-site可以任意指定这个地方所需要的variance。所以你在use-site既可以写出 List<? extends Fruit> ,也可以写出 List<? super Fruit> ,就看你需要的是什么(是producer?consumer?)。这不是表象啊真实啊啥的问题。 非常感谢及时的回答。OTZ --引用前文--- 这样,如果有 T <: U 此时如果 G[T] <: G[U],那么G这种变换就是covariant的; 反之,如果 G[U] <: G[T],那么这种变化就是contravariant的。 --引用前文--- 我所谓的"表现的像,并非真正的协变",是指java中,存在T<:U => G[from T]<:G[from U]。 请用java中带wildcard的List来说明以上定义。 |
|
返回顶楼 | |
发表时间:2012-02-16
在use-site,
假设有 T <: U 那么 G<T> <: G<? extends U> 表达了covariance G<U> <: G<? super T> 表达了contravariance 真实不? |
|
返回顶楼 | |
发表时间:2012-02-17
RednaxelaFX 写道 在use-site,
假设有 T <: U 那么 G<T> <: G<? extends U> 表达了covariance G<U> <: G<? super T> 表达了contravariance 真实不? 非常感谢,我得把use-site、declaration-site的covariance分开对待。 不过想想,表达的都是同一个意思。 |
|
返回顶楼 | |
发表时间:2012-02-17
mwei 写道 RednaxelaFX 写道 在use-site,
假设有 T <: U 那么 G<T> <: G<? extends U> 表达了covariance G<U> <: G<? super T> 表达了contravariance 真实不? 非常感谢,我得把use-site、declaration-site的covariance分开对待。 不过想想,表达的都是同一个意思。 嗯,要说“真实”的话,都是真实的。 只是declaration-site variance使variance成为了“G”的内在属性,所以在使用“G”的时候自然就是covariant或者contravariant的; 而use-site variance的方式里,“G”本身是invariant的,必须“外在”的指定variance。这样比较灵活但恐怕对多数人反而不直观吧。 |
|
返回顶楼 | |
发表时间:2012-02-17
最后修改:2012-02-17
目前深陷递归泛型漩涡,不知怎么解决
public class AbstractRecursiveRelation<T extends AbstractRecursiveRelation<T,C>,C extends Collection<T>> implements Relation<T> { private C self; private C others; public AbstractRecursiveRelation(C self, C others) { this.self = self; this.others = others; } @SuppressWarnings("unchecked") private T thiz(){ return (T)this; } public void build(T another){ another.others.add(thiz()); self.add(another); } public void destory(T another){ another.others.remove(this); self.remove(another); } public void notifyToDestory(){ Relations.allDestoryOne(Relations.filterIn(this, filter()), thiz()); } protected Filter<T> filter(){ return new Filter<T>() { @Override public boolean filter(T t) { return true; } }; } public boolean contains(Object another){ return self.contains(another); } public boolean in(Object another){ return others.contains(another); } public Iterable<T> members(){ return new ArrayList<T>(self); } public Iterable<T> onwers(){ return new ArrayList<T>(others); } } 暂时是使用一个毫无意义的中间类来绕过,蛋疼死 public class CommonRecursiveRelation extends AbstractRecursiveRelation<CommonRecursiveRelation, Collection<CommonRecursiveRelation>>{ public CommonRecursiveRelation(Collection<CommonRecursiveRelation> self, Collection<CommonRecursiveRelation> others) { super(self,others); } } |
|
返回顶楼 | |
发表时间:2012-02-17
如果你想了解更多的类型推断,可以参考一下scala在类型推断中怎么作的。
|
|
返回顶楼 | |
发表时间:2012-02-17
最后修改:2012-02-17
RednaxelaFX 写道 嗯,要说“真实”的话,都是真实的。 只是declaration-site variance使variance成为了“G”的内在属性,所以在使用“G”的时候自然就是covariant或者contravariant的; 而use-site variance的方式里,“G”本身是invariant的,必须“外在”的指定variance。这样比较灵活但恐怕对多数人反而不直观吧。 对,反而不直观。 再次回到定义,如果有T <: U,此时如果 G[T] <: G[U],那么G这种变换就是covariant的; 这里的T,U,G[T],G[U]在我眼里都是"定数"。 而java里的--假设有T <: U, 那么G<T> <: G<? extends U> 表达了covariance;这里"? extends U"存在"变数"。结果就不直观了... 本想法私信请教撒迦的,这里就继续追问吧。如下代码,先不考虑它是否有意义: abstract class Cat[in T, out U]{ def meow[W](volume:T,listener:Cat[U,T]):Cat[Cat[U,T],U] } 这是Scala书里的代码,我只是把参数类型T,U的注解"+","-"对应的替换成了C#里的out,in; 有什么方法能用来判断这里的T,U所在的位置都是合法的? 问这个问题,主要是Programming In Scala 2nd.pdf 19.4节没有看懂. |
|
返回顶楼 | |
发表时间:2012-02-17
最后修改:2012-02-17
buptwhisper 写道 如果你想了解更多的类型推断,可以参考一下scala在类型推断中怎么作的。
Scala的类型推断很优秀,不过Scala里的泛型应该是declaration-site。还没在《Programming In Scala 2nd》里看到关于bounded wildcard type(MyCollection<? relation SomeObj>)的使用。 |
|
返回顶楼 | |