1、先说class.forName("")
先看API
public static Class<?> forName(String className)
throws ClassNotFoundException返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
Class.forName(className, true, currentLoader)(此来源Class的另一个方法
public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException)
其中 currentLoader 表示当前类的定义类加载器。
例如,以下代码片段返回命名为 java.lang.Thread 的类的运行时 Class 描述符。
Class t = Class.forName("java.lang.Thread")
调用 forName("X") 将导致命名为 X 的类被初始化。
true表示用加载器加载这个类生成Class对象的同时,并且初始化这个类。
package com.testclass;
public class TestClass {
public static void main(String[] args) {
try {
Class c = Class.forName("com.testclass.Test");
System.out.println(c.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Test {
static {
System.out.println("执行静态块,初始化类");
}
public Test() {
System.out.println("构造方法执行");
}
}
输出:
执行静态块,初始化类
com.testclass.Test
说明当使用Class.forName("")进行反射生成Class对象的时候,执行了这个类的静态代码,初始化了这个类
补充:Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象 Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段 (来源http://blog.csdn.net/ozwarld/article/details/8277361)
2、类名.class
JVM将使用类A的类装载器,将类A装入内存(前提是:类A还没有装入内存),不对类A做类的初始化工作.返回类A的Class的对象
package com.testclass;
public class TestClass {
public static void main(String[] args) {
Class c = Test.class;
System.out.println(c.getName());
}
}
class Test {
static {
System.out.println("执行静态块,初始化类");
}
public Test() {
System.out.println("构造方法执行");
}
}
输出:
com.testclass.Test
也就是说利用类名.class进行反射生成Class对象的时候,不会初始化这个类,更不会执行这个类的静态代码
3、对象.getClass()
Class cl=对象引用.getClass();返回引用o运行时真正所指的对象所属的类的Class对象(因为:儿子对象的引用可能会赋给父对象的引用变量中,也就是上转型对象)
就是现有对象然后再通过这个对象用Class cl=对象引用.getClass()得到Class对象
但是在静态方法中不能用this.getClass()得到这个类的Class对象。原因当然是静态方法中不能用this的原因了