论坛首页 Java企业应用论坛

关于Java泛型 与 类型推断

浏览 21823 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (1) :: 隐藏帖 (12)
作者 正文
   发表时间:2012-02-15  
其实我没明白楼上说的:表现的像协变,与真正协变怎么个去理解。。

不太明白你这两个概念。
0 请登录后投票
   发表时间: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?)。这不是表象啊真实啊啥的问题。
0 请登录后投票
   发表时间: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来说明以上定义。
0 请登录后投票
   发表时间:2012-02-16  
在use-site,

假设有
T <: U
那么
G<T> <: G<? extends U> 表达了covariance
G<U> <: G<? super T> 表达了contravariance

真实不?
0 请登录后投票
   发表时间: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分开对待。
不过想想,表达的都是同一个意思。
0 请登录后投票
   发表时间: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。这样比较灵活但恐怕对多数人反而不直观吧。
0 请登录后投票
   发表时间: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);
	}	
}

0 请登录后投票
   发表时间:2012-02-17  
如果你想了解更多的类型推断,可以参考一下scala在类型推断中怎么作的。
0 请登录后投票
   发表时间: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节没有看懂.


0 请登录后投票
   发表时间:2012-02-17   最后修改:2012-02-17
buptwhisper 写道
如果你想了解更多的类型推断,可以参考一下scala在类型推断中怎么作的。

Scala的类型推断很优秀,不过Scala里的泛型应该是declaration-site。还没在《Programming In Scala 2nd》里看到关于bounded wildcard type(MyCollection<? relation SomeObj>)的使用。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics