阅读以下程序,写出输出结果:
public class ForNameFunctionTest
{
public static void main(String[] args) throws Exception
{
System.out.println("Hello World!");
System.out.println("new Zoo before!");
Class c = Class.forName("Dog");
System.out.println("initial before!");
Animal dog = (Animal) c.newInstance();
System.out.println("new Zoo after!");
}
}
abstract class Animal
{
static{
System.out.println("Animal static code block!");
}
//抽象类构造方法
Animal(){
System.out.println("Animal Contruct!");
}
}
class Dog extends Animal
{
static{
System.out.println("Dog static code block!");
}
public Dog(){
System.out.println("Dog Construct!");
}
}
类的生命周期:
加载—验证—准备—解析—初始化—使用—卸载
Class.forName():返回一个类对象
上述语句会引发加载过程,也就是说JVM会执行该类的静态代码段,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了
这句话执行了”加载—验证—准备—解析—初始化(类的初始化)“,即将一个类加载到内存中,并最终形成虚拟机直接使用的Java类型。这个过程会执行static块。
对象实例化:
- new
- newInstance()
两者的区别:
- 首先,newInstance( )是一个方法,而new是一个关键字;
- 其次,Class下的newInstance()的使用有局限,因为它生成对象只能调
用无参的构造函数,而使用 new关键字生成对象没有这个限制。
简言之:
- newInstance(): 弱类型,低效率,只能调用无参构造。
- new: 强类型,相对高效,能调用任何public构造。
- Class.forName(“”)返回的是类。
- Class.forName(“”).newInstance()返回的是object 。
回归正题:
运行之后的结果:
首先是forName(“Dog”),此时加载Dog父类(Animal),接着Dog类,加载过程中执行static静态块。
接着newInstance(),实例化一个对象,依据构造函数链,调用构造函数。
也可以知道
Class c = Class.forName("Dog");
Animal dog = (Animal) c.newInstance();
就相当于
Animal dog = new Dog();