java中的类型依赖

来源:互联网 发布:宇喜多秀家数据 编辑:程序博客网 时间:2024/06/05 09:44

原文链接:https://www.javaworld.com/article/3172592/java-language/type-dependency-in-java-part-1.html

1. 兼容是单向关系,引用类型的兼容性一般发生在同一类型层次结构中;

引用类型结构中,A隐式兼容B,因此有 B = A 赋值成功;一般情况下,B是A的父类,A = (A) B;必须显式转型。举个例子,Number是Integer的父类,因此有:

number = integer; 

integer =(Integer) number; 

Integer隐式兼容Number, Number显式兼容Integer. 总结来说,子类隐式兼容父类,父类显式兼容子类。向上转型采用隐式,向下转型采用显式。

Boolean与任何类型都不兼容,基本类型与引用类型不兼容。

 基本类型的兼容顺序

2. 类型依赖的几种情况:

(1) 数组,int[] 依赖基本类型int;

(2) 泛型,ArrayList<T>依赖类型对象类型T;

(3) 方法,依赖参数类型;


3. 协变和逆变(Covariance andcontravariance)

协变是指两个类型的兼容隐含依赖它们的两个类型的兼容。T1向T2兼容,则A(T1)向A(T2)兼容,依赖类型A(T)称为协变,A(T1) 是A(T2)的协变。


Integer[] integerArray;

Number[] numberArray;

numberArray = integerArray;

integerArray = ( Integer[] ) numberArray;

/**

Integer[] 是Number[]的隐式协变

Number[]是Integer[]的显式逆变

*/


如果T1向T2兼容,可以得出A(T2)向A(T1)兼容,则A(T)称为逆变。若T1与T2兼容,A(T1)并不与A(T2)兼容,则A(T)是不变式。Java中的数组并不支持隐式的逆变,只支持显式。基本类型的数组是不可变的。泛型是隐式不变的,可以使用通配符<?>接收任何类型的参数,由于该通配符是抽象的,只能作为引用,不能实例化。


Generic<SuperType> superGeneric;

Generic<SubType> subGeneric;

subGeneric =(Generic<SubType>)superGeneric; // type error

superGeneric = (Generic<SuperType>)subGeneric;// type error


若要使Generic<SubType>兼容Generic<SuperType>,可以使用<? extendsSuperType>兼容SuperType及它的子类;

Generic<? super SuperType> 可以兼容Super和它的父类。


4. Collection API中的兼容性设计

Collection.sort( List< T extendsComparable< ? super T>>)

这样设计的原因是element中的compareTo( Object o ) 的参数以element定义或者其父类类型,因此使用<? Super T >.

T extends Comparable< ? super T>既有协变也有逆变,采用<? super T>的好处在于sort接受的参数类型T可以不用直接实现compareTo方法,只要其父类中实现即可,若其父类实现了compareTo方法,编译器不会要求T实现compareTo方法。


5. 泛型类中,不能使用参数类型创建实例。object= new E(); //type error


总结:

隐式转型(协变)由编译器断言,显式(逆变)有编程者断言,向上转型多是前者,向下转型一般是后者。通配符?兼容所有object,但是反之不成立。方法签名由方法的参数类型与参数个数区别。阅读原文查看原文章~