您的位置:首页 > 其它

type接口和class的区别(类型和类)

2018-02-02 18:05 190 查看
Class
public final classClass<T>implementsjava.io.SerializableGenericDeclarationTypeAnnotatedElement
{


}

Type
public interface
Type
{  
default String
getTypeName() {
return
toString
();
}
}
以上是类和接口的代码。

Class 类的实例也就是对象表示正在运行的 Java 应用程序中的类(class)和接口(type),从JDK的源码可以看出type是class实现的一个接口,Type是一个空接口是所有类型的公共接口也就是父接口,其意义表示Java所有类型,class是对于现实对象的抽象每一个实例对象是其class 的一个实例,class可以看成是类实例的类,每一个类被加载到JVM中都会产生唯一的一个类实例,记录类型的详细信息,如A类被加载到JVM中会产生一个类实例,其类型为Class,可以通过A.class获得这个类实例。而type是对Java语言的对象而言,这里的类型是对于java语言而言,比如原始类型、参数化类型(泛型)、类型变量及其数组等.

注意区分类型(Type)与类(Class)的区别,这里Class是Type的一种是Type的子集,直接子类只有一个也就是Class,代表着类型中的原始类型以及基本类型。,而像数组、枚举等“类型”是相对于Class来说。

  Type是JDK5开始引入的,其引入主要是为了泛型,没有泛型的之前,只有所谓的原始类型。此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。 泛型出现之后,也就扩充了数据类型。从只有原始类型扩充了参数化类型、类型变量类型、泛型数组类型,也就是Type的子接口。那为什么没有统一到Class下,而是增加一个Type呢?(Class也是种类的意思,Type是类型的意思,是为了程序的扩展性,最终引入了Type接口作为Class,ParameterizedType,GenericArrayType,TypeVariable和WildcardType这几种类型的总的父接口。这样实现了Type类型参数接受以上五种子类的实参或者返回值类型就是Type类型的参数。

1: 类型的概念 
概念:类型刻划了一组值及其上可施行的操作,可理解为值集和操作集构成的二元组。 类型的概念与值的概念相对立,前者是程序中的概念,后者则是程序运行时的概念,两者通过标识值的语言成分(例如,变量、表达式等)联系起来。 比如变量v说明为具有类型T,类型T所刻划的值集为{v1,v2,…vn,…},则变量v运行时能取且只能取某个vi为值。由此可见,类型规定了具有该类型的变量或表达式的取值范围。 

2: 类与类型 
A: 共性 :在对象式语言中,“值”为对象(或对象索引,但本质上仍为对象)。所以对象式语言中的类型刻划了一组对象上可施行的操作。类也刻划了一组对象以及其上的操作。 两者的共性在于二者均刻划了一组对象及其上的操作,所以既可以说对象是类型的实例,也可以说对象是类的实例,类型和类在与对象的关系上是相同的。不过,类型欲刻划一组对象上的操作必须借助于类,因为类是达到这种目的的唯一设施。由此可见类型是以类为基础的,是通过类来定义的,这体现了二者的联系。 

B: 区别 
(1)作用不同 :类是程序的构造单位,是描述一组对象及其上操作的唯一语言成分,故其作用主要是具体描述这组对象,提供运行时创建这些对象的“模板”。例如,基于类间的继承关系的派生类定义设施就反映了类在描述对象方面的作用。 类型则不是,它只是标志变量或表达式取值范围的一种语言成分。

(2)与对象联系的紧密程序不同 :类描述对象的具体形式和其上可施行的具体操作,且强调所描述的一组对象的共性,因而,与具体对象联系较密切,而与对象集的大小则联系较少。 类型强调所描述的一组对象的范围和可施行操作的范围,与对象集的大小联系较密切,而与其中具体对象则联系较少。 

(3)不是所有类都可直接作为类型使用 :类是类型的基础,类型靠类来定义,有些类可直接作为类型来使用,在这种意义下,我们也可称这些类是类型。 但是,也有一些类不能直接作为类型来使用,这是因为,从类型的约束作用来看,类型强调所刻划的对象的确定性,即对象范围的确定性。因此,只有所描述的对象的范围确定的类才可直接用作类型。

对象操作所定义的所有操作型构的集合被称为接口,该接口描述了该对象所能接受的全部请求,任何匹配对象接口中型构的请求都可以发送給该对象。

类型是用来标识特定接口的一个名字,如果一个对象接受某个接口所定义的所有操作请求,就可以认为该对象具有这个类型,接口可以包含其他接口作为子集,当一个类型的接口包含另外一个类型的接口时,我们就说它是另一个类型的子类型。当給对象发送请求时,所引起的具体操作与请求本身和接受的对象有关,支持相同请求的不同对象可能对请求激发的操作有不同的实现,发送給对象的请求和它相应的操作在运行时刻的连接称之为动态绑定,即是指发送的请求直到运行的时刻才受你的具体实现的约束。

设计模式根据通过确定接口的主要组成部分及接口发送的数据类型,来帮助使用者定义接口,还会告诉使用者不能包含哪些东西,同时也指定了接口之间的关系。

描述对象的实现

对象的实现是由类定义的,类指定了对象内部的数据和表示,也定义了对象能够完成的操作。

抽象类的主要目的是为了它的子类定义公共接口,一个抽象类将把它的部分或全部操作的实现延伸到子类中。而混入类是给其他类提供可选择的接口或功能的类,域抽象类一样不能实例化。

类继承与接口的比较:首先理解对象的类与对象的类型的区别很重要,一个对象的类定义了对象是怎么实现的,但是对象的类型只与它的接口有关,不同类的对象具有相同的类型,同时对象的类和类型也是具有紧密联系的,因为类定义了对象所能执行的操作,也定义了对象的类型,当说一个对象是一个类的实例时,即指该对象支持类所定义的接口。然后回到继承和接口,类继承根据一个对象的实现定义了另外一个对象的实现,简而言之就是代码和表示的共享机制,但是接口继承描述了一个对象什么时候可以被另外一个对象替代,很多语言不区分这两个概念,所以容易混淆。尽管大部分设计语言不区分接口继承和实现继承这两个的区别但是使用中还是分别对待它们,很多设计模式依赖于这种差别,比如说一个模式中的对象必须有一个公共类型,但一般情况下它们不具有公共的实现。

对接口编程,虽然类继承允许从已存在的类中继承所需要的绝大部分功能,就可以获得新的实现,然和实现的复用只实现了一半,定义具有相同接口的对象族这一功能很重要,因为多态需要这种能力,只根据抽象接口编程有两个好处:客户无需知道使用对象的特定类型,只需对象有客户所期望的类型,无须知道使用的对象是用什么类来实现的,只须知道定义接口的抽象类。这将极大的减少子系统实现之间的相互依赖关系,也产生了可复用的看向对象的设计原则,针对接口编程而不是针对实现编程。

不将变量声明某个特定的具体类的实例对像,而是遵从抽象类所定义的接口。

  

Type的直接子接口

1.ParameterizedType: 表示一种参数化的类型,比如Collection,即普通的泛型。 

2.TypeVariable:是各种类型变量的公共父接口,就是泛型里面的类似T、E。 

3.GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型,比如List<>[],T[]这种。 

4.WildcardType:代表一种通配符类型表达式,类似? super T这样的通配符表达式。

Type子接口解析

1.ParameterizedType:参数化类型,即泛型,类似List<T>、Map<Integer, String>、List<? extends Number>带有类型参数的类型,也可以是自定义的,再调用getRawType()与getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([?
super T]),而这个? super T又是一个WildcardType类型。 

public interface
ParameterizedType extendsType {

//1.获得<>中实际类型

Type[] getActualTypeArguments();

//2.获得<>前面实际类型

Type getRawType();

//3.如果这个类型是某个类型所属,获得这个所有者类型,否则返回null

Type getOwnerType();

 }

2.TypeVariable:类型变量,如参数化类型中的E、K等类型变量,表示泛指任何类,如果加上extends/super限定,则就会有相应的上限、下限。 
publicinterface
TypeVariable<DextendsGenericDeclaration>extends
Type {
//获得泛型的上限,若未明确声明上边界则默认为Object
Type[] getBounds();
//获取声明该类型变量实体(即获得类、方法或构造器名)
D getGenericDeclaration();
//获得名称,即K、V、E之类名称
String getName();
 }

3.GenericArrayType:泛型数组,表示上面两种的数组类型,即形如:A<T>[],T[][]类型。 

public interfaceGenericArrayTypeextendsType {

//获得这个数组元素类型,即获得:A<T>(A<T>[])或T(T[])

Type getGenericComponentType();

//获取泛型数组中元素的类型,要注意的是:无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。

}

以下是getGenericComponentType()函数的源码
classA<K>[][] key;
Type
type = Main.class.getDeclaredField("key").getGenericType();
System.out.println(((GenericArrayType)type).getGenericComponentType());
//输出结果
//com.fcc.test.classA<K>[]

4.WildcardType:通配符表达式,或泛型表达式,它虽然是Type的一个子接口,但并不是Java类型中的一种,表示的仅仅是类似 ? extends T、? super K这样的通配符表达式。 
publicinterface
WildcardTypeextends
Type {
//获得泛型表达式上界(上限)
Type[] getUpperBounds();
//获得泛型表达式下界(下限)
Type[] getLowerBounds();
 }

Java的所有类型包括: 

1. raw type:原始类型,对应Class ,不仅仅指平常所指的类,还包括数组、接口、注解、枚举等结构。 

2. parameterized types:参数化类型,对应ParameterizedType 

3. array types:数组类型,对应GenericArrayType ,应该指的是2、4类型的数组而不是一般我们说的数组,一般所说的数组是指1、5类型数组,它们依旧属于1,也就是Class类型。

4. type variables:类型变量,对应TypeVariable 

5. primitive types:基本类型,仍然对应Class 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐