Class.forName、类.class、实例对象.getClass的区别

1.java的反射机制

每个java程序执行前都必须经过编译、加载、连接和初始化这几个阶段,后三个阶段

加载:查找并加载类的二进制数据

连接:a.验证: 确保被加载类的正确性

           b.准备:为类的静态变量分配内存,并将其初始化为默认值

           c.解析:把类中的符号引用转换为直接引用

初始化:为类的静态变量赋予正确的初始值。

1)加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!。

2)在 连接和初始化阶段,其实静态变量经过了两次赋值:第一次是静态变量类型的默认值;第二次是我们真正赋给静态变量的值。

3)Java对类的使用分为两种方式:主动使用和被动使用

主动使用:a.创建类的实例

                  b.访问某个类或接口的静态变量,或者对该静态变量赋值

                  c.调用类的静态方法

                  d.反射(如Class.forName("com.caiminghong.xxx"))

                  e.初始化一个类的子类

                  f.Java虚拟机启动的时候被标明为启动类的类(WebAplication)

而类的初始化时机正是java程序对类的首次主动使用,除了以上6中方式,其他对类的使用都是被动使用,都不会导致类的初始化。

并且应该注意以下几个方面:

a.调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化。

b.当Java虚拟机初始化一个类时,要求它的所有父类都已经被初始化,但是这个规则并不适用于接口。在初始化1个类时,并不会先初始化它所实现的接口。在初始化一个接口的时候,并不会先初始化它的父接口。因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定接口的静态变量时候,才会导致该接口的初始化。可以看出接口的两重性:可以把接口当类(接口中有静态变量时,它可以被初始化),接口就是接口,和类无关(接口中 没有构造方法,所有不能被初始化)

2.Class.forName、类.class、实例对象.getClass的区别

1)相同点

通过这几种方式,得到的都是Java.Lang.Class对象(这是上面讲到的,类在加载时获得的最终产物)

2)区别

 1)Class cl=A.class; JVM将使用类A的类装载器,将类A装入内存(前提是:类A还没有装入内存),不对类A做类的初始化工作.返回类A的Class的对象

2)Class cl=对象引用o.getClass();返回引用o运行时真正所指的对象(因为:儿子对象的引用可能会赋给父对象的引用变量中)所属的类的Class的对象 

3)Class.forName("类名"); JAVA人都知道.装入类A,并做类的初始化

3.new A() 和 Class.newInstance()区别

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

2)Class对象的newInstance()(这种用法和Java中的工厂模式有着异曲同工之妙)实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。 

3)最后用最简单的描述来区分new关键字和newInstance()方法的区别: 
newInstance: 弱类型。低效率。只能调用无参构造。 
new: 强类型。相对高效。能调用任何public构造。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值