版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28666081/article/details/86662797
总结如下:
- java可通过5种来创建实例化一个对象(new、反射、Class.forName、clone、序列化),多的不讲,就说说反射与Class.forName
- 从下面的代码可分析出如果在当前类没有加载到jvm前,代码中步骤1、2、3在没有调用newInstance()之前均只是执行到了<clinit>阶段(当然类加载进jvm后,即便执行如Class.forName("xxx")、Person.class等,对应的静态代码块也不会在执行一遍),即只是调用了静态代码块(这也是为什么加载mysql驱动式只需要Class.forName来初始化了)。只有在调用newInstance()后才会执行<init>阶段后的成员变量的初始化、构造函数的调用。
注:下面代码的三个步骤1、2、3中在没有执行newInstance()前返回的是类,执行后返回的是对象。
代码如下:
public class Demo14 {
@Test
public void test01() throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
// 1、通过"对象.getClass()" 创建对象
Person p1 = new Person();
Person c1 = p1.getClass().newInstance();
Person c2 = p1.getClass().newInstance();
System.out.println(p1.getClass() == p1.getClass()); //true,都是同一个类
System.out.println(c1 == c2); //false,不同的实例
// 2、通过"类.class" 创建对象
Person c3 = Person.class.getConstructor().newInstance(); //指定构造方法
System.out.println(c3);
Person c4 = Person.class.newInstance(); //不指定默认用无参构造
System.out.println(Person.class == Person.class); //true,都是同一个类
System.out.println(c3 == c4); //false,不同的实例
// 3、Class.forName 创建对象
Class<?> c5 = Class.forName("spring.Person"); //直接传入包名就可获取对应的类
System.out.println(c5.newInstance());
}
}
class Person {
//类变量
private static String staticVal = "============》person static val";
//实例成员变量
private String val = "============》person val";
//静态代码块
static {
System.out.println("============》person static block:" + staticVal);
}
//代码块
{
System.out.println("============》person block:" + val);
}
//构造方法
public Person() {
super();
System.out.println("============》person Constructor:" + val);
}
//实例成员方法
public void test() {
System.out.println("============》person test method");
}
}