Java -Class

Java Class

类字面常量

Java生成对Class对象的引用,Class bean = bean.class\
当使用".class"来创建Class对象引用时,不会自动地初始化该Class对象。为了使用类而做的准备工作实际包含三个步骤:
1. 加载,这是由类加载器执行的。该步骤将查找字节码(通常在classpath所指定的路径中查找,但这并非是必需的),并从这些字节码中创建一个Class对象。
2. 链接。在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的引用。
3. 初始化。如果该类具有超类,则将其初始化,执行静态初始化器和静态初始化代码块。
初始化被延迟到了对静态方法(构造器隐式地是静态的)或者非常数[not final]静态域进行首次引用时才执行.

如果是一个static fina值是"编译期常量",那么这个值不需要对类进行初始化就可以被读取。但是,如果只是将一个域设置为static和final的,不足以确保这种行为,`static final int staticFinal2 = ClassInitialization.rand.nextInt(1000);` 这种情况将强制进行类的初始化,因为他不是个编译期常量。

泛化的Class引用

Class引用总是指向某个Class对象,他可以制造类的实例,并包含可作用于这些实例的所有方法代码。它还包含该类的静态成员。因此,Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象。
向Class引用添加泛型语法的原因仅仅是为了提供编译期类型检查。

Class.forName("")得到的是Class对象
intClass.newInstance得到的是Object对象

instanceof与Class的等价性
instanceof保持了类型的概念,它指得是"你是这个类吗,或者你是这个类的派生类吗?"
而如果用==比较实际的Class对象,就没有考虑继承————它或者是这个确切的类型,或者不是。

反射:运行时的类信息

如果不知道某个对象的确切类型,RTTI可以告诉你,但是如果这个类型在编译时无法确定,这时候就无能为力了。
当通过反射与一个未知类型的对象打交道时,JVM只是简单地检查这个对象,看他属于哪个特定的类(就像RTTI那样)。在用它做其他事情之前IXUS先加载哪个类的Class对象。因此,哪个类的.class文件对于JVM来说必须是可获取的。要么在本地机器上,要么通过网络获得。所以RTTI和反射之间真正的区别只在于,对RTTI来说,编译期在编译时打开和检查.class文件。(换句话说,我们可以用“普通”方式调用对象的所有方法。)而对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。

反射类(例如Method)可以在java.lang.reflect中找到。要使用这些类,必须遵循三个步骤。
第一步是为java.lang.Class要操作的类获取一个对象。java.lang.Class用于表示正在运行的Java程序中的类和接口。

获得Class对象的一种方法是说:

//获取的Class对象String。
Class c = Class.forName("java.lang.String"); 
//另一种方法是使用: 
Class c = int.class; // ==  Class c = Integer.TYPE;

获取有关基本类型的Class信息。后一种方法访问基本类型TYPE的包装器的预定义字段(例如Integer)。
第二步是调用诸如getDeclaredMethods之类的方法,以获取该类声明的所有方法的列表。

一旦掌握了这些信息,那么第三步就是使用反射API来操纵信息。例如,序列:

Class c = Class.forName("java.lang.String"); 
Method m[] = c.getDeclaredMethods(); 
System.out.println(m[0].toString());

将显示在中声明的第一个方法的文本表示形式String。

reflect的相关文档:

  • https://www.oracle.com/technical-resources/articles/java/javareflection.html

类方法提取器

动态地提取某个类的信息

Class<?> c  = Class.forName("String");
Method[] methods = c.getMethods(); //返回Method对象数组
Constructor[] constructors = c.getConstructors(); //返回Constructor对象数组

Class.forName()生成的结果在编译时是不可知的,因此所有方法特征的签名信息都是在执行时被提取出来的。

动态代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值