首页 > 编程知识 正文

class种类的用法,class类定义

时间:2023-05-05 04:10:08 阅读:190371 作者:54

1 .简介在Java的世界里,一切都是对象。 从某种意义上说,Java有两种类型的对象:实例对象和类对象。 每个类的运行时类型信息都由Class对象表示。 包含有关类的信息。 实际上,实例对象是从Class对象创建的。 Java使用Class对象执行其运行时类型标识(RTTI ),多态性是基于RTTI实现的。

每个类都有一个类对象,每次编译新类时都会生成一个类对象。 基本类型(boolean、int等)包括类对象、数组和关键字void也包括类对象(void.class )。 Class对象对应于java.lang.Class类,即类是对象抽象和集合Class类就是对类的抽象和集合

Class类没有通用的构造方法。 在类加载时通过调用Java虚拟机和类加载器中的defineClass )方法自动构建Class对象,因此显式声明Class对象是因为要将一个类加载到内存中并使其可用,需要三个阶段:

加载这由类加载器(ClassLoader )执行。 获取由类的完全限定名称定义的二进制字节流(Class字节码),将该字节流表示的静态存储结构转换为方法区域的运行时数据接口,并根据字节码在Java堆中表示该类的Java堆在链接链接阶段,验证Class文件中的字节流中包含的信息是否满足当前虚拟机的要求,为静态域分配存储空间,将类变量的初始值(默认零初始化只有在此阶段,类中定义的Java程序代码才能真正开始执行。 运行类的静态启动器和静态启动器。 如果类具有父类,则其父类将优先初始化。 *所有类在第一次使用时动态加载到JVM中。 *当程序创建对类的静态成员的第一个引用时,将加载该类。 使用new创建类对象时,它也用作对类的静态成员的引用。因此java程序程序在它开始运行之前并非被完全加载,其各个类都是在必需时才加载的。

在类的加载阶段,类加载器首先检查是否已加载了该类的Class对象。 如果未加载,则缺省类加载器将根据类的全限定名称搜索. class文件。 此类的字节码加载后,将经过验证以确保其未被破坏且不包含有故障的Java代码。 将类的Class对象加载到内存中后,可以创建该类的所有对象。

也就是说,在内存中创建此类的Class对象,然后使用此Class对象创建特定的实例对象。

2 .获得class对象(类型类),可以从class对象确定对象的真实类型。 有三种获取Class对象的方法。

class.forname(Stringname,boolean initialize, ClassLoader loader ) )类名. class实例对象. getClass )。注意:在第一种方法中,如果使用只有一个string参数的forrrass,则string参数为类如果不成功,则抛出ClassNotFoundException异常。

如果将initialize设置为false,则在使用类创建对象时执行静态块,而不是在加载类时立即执行。

常用的对象直接或间接从Object类继承。 Object类包含一个名为getClass ()的方法,可以使用该方法获取实例的Class对象(类型类)。 因为一切都是对象,班级也不例外。 例如,下面的代码可能类似于:

A a=new A (; if(a.getclass(==a.class ) system.out.println ) ' equal ); else system.out.println (' unequal ); //可以通过equal知道打印结果,对象a是a的实例,使用a.getClass )返回的结果正是a的类型类,通过类名. class获得的也是a的类型类。 也就是说,两者是等效的,是使用类的实例,是使用类名的实例。

需要特别注意的是,类型类是一对一的,父类和子类的类型类不同。 因此,假设a是b的子类,则以下代码将获得" unequal "的输出:

A a=new A (; if(a.getclass(==b.class ) system.out.println ) ' equal ); else system.out.println (' unequal ); //因为结果为unequal,所以如果您知道实例,请使用实例的实例. getClass (

)方法获得该对象的类型类,如果你知道一个类型,那么你可以使用类名.class的方法获得该类型的类型类。

补充

Class.forName().newInstance() 和 new 关键字创建对象实例的异同

在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。

那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。

Java中工厂模式以及使用Java反射机制时经常使用newInstance()方法来创建对象,例如:

class c = Class.forName("Example"); factory = (ExampleInterface)c.newInstance();

从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。

现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。

最后用最简单的描述来区分new关键字和newInstance()方法的区别:

newInstance(): 弱类型。低效率。只能调用无参构造。new: 强类型。相对高效。能调用任何public构造。 3. 获得类型的信息

getClassLoader():获取该类的类装载器。

getName():String:获得该类的完全名称。

getConstructor(Class[]) :返回当前Class对象表示的类的指定的公有构造子对象。

getConstructors() :返回当前Class对象表示的类的所有公有构造子对象数组。

getDeclaredConstructor(Class[]) :返回当前Class对象表示的类的指定已说明的一个构造子对象。

getDeclaredConstructors() :返回当前Class对象表示的类的所有已说明的构造子对象数组。

getDeclaredField(String) :返回当前Class对象表示的类或接口的指定已说明的一个域对象。

getDeclaredFields() :返回当前Class对象表示的类或接口的所有已说明的域对象数组。

getDeclaredMethod(String,Class[]) :返回当前Class对象表示的类或接口的指定已说明的一个方法对象

getDeclaredMethods() :返回Class对象表示的类或接口的所有已说明的方法数组。

getField(String) :返回当前Class对象表示的类或接口的指定的公有成员域对象。

getFields() :返回当前Class对象表示的类或接口的所有可访问的公有域对象数组。

getInterfaces() :返回当前对象表示的类或接口实现的接口。

getMethod(String,Class[]) :返回当前Class对象表示的类或接口的指定的公有成员方法对象。

getMethods() :返回当前Class对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。

newInstance() :创建类的新实例。

getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。

getInterfaces():Class[]:获得该类型实现的所有接口。

isArray():boolean:判断该类型是否是数组。

isEnum():boolean:判断该类型是否是枚举类型。

isInterface():boolean:判断该类型是否是接口。

isPrimitive():boolean:判断该类型是否是基本类型,即是否是int,boolean,double等等。

isAssignableFrom(Class cls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。

getComponentType() :如果当前类表示一个数组,则返回表示该数组组件的Class对象,否则返回null。

更多阅读:Java API

关注微信公众号:【三朝猿老】 获得更多最新信息

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。