学习自《think in java》chapter.14.类型信息
1,xxx.java文件经过编译后产生xxx.class文件,JVM根据该.class文件该类的产生Class对象。每个类都有Class对象,从Class对象中可以获得类的信息(构造,域,方法),生成实例对象,或者调用方法。
2,关于类加载,Java对类的加载是动态的,什么时候需要,什么时候加载,通常,当程序创建第一个类的静态成员的引用时,JVM检查该类是否有加载过,若无,则加载之。
eg: new Someth(); //调用构造方法,而构造方法是静态的
此外,引用 static final的域不会初始化
3,Class.forName("包名.类名");返回该类的Class对象;
某类XXX.class 也是Class对象的引用;两者有什么区别?answer is : Class.forName("包名.类名")会顺便初始化类,而XXX.classz就不会初始化。
eg:
public class ClassLoad {
public static void main(String[] args) {
try {
<strong>//得到一个类对象(对象的 Class对象),并且初始化类</strong>
Class classA = Class.forName("t1.ClassA");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
<strong>//.class(类字面常量)这样仅仅得到一个类的Class对象,但并未出始化</strong>
Class classB = ClassB.class;
System.out.println("<strong>在未使用类之前,引用类的static final值,不会被初始化</strong>");
System.out.println("static fianl:"+ClassC.sf1);
System.out.println("在未使用类之前,引用类的非static final静态域,会被初始化");
//System.out.println("not static fianl:"+ClassC.sf2);
ClassC.methodTest();
}
}
// class
class ClassA{
//初始化时候会执行静态语句
static{
System.out.println("ClassA is init");
}
}
public class ClassB{
static{
System.out.println("ClassB is init");
}
}
class ClassC{
public static final int sf1 = 10;
public static int sf2 = 20;
static{
System.out.println("ClassC is init");
}
public static void methodTest(){
System.out.println("static method in ClassC");
}
}
结果:
ClassA is init
在未使用类之前,引用类的static final值,不会被初始化
static fianl:10
在未使用类之前,引用类的非static final静态域,会被初始化
ClassC is init
static method in ClassC
4,若存在实例了 ,假设实例obj, obj.getClass(); 返回实例对应的类的类对象,即类的Class对象。
若存在类对象的引用,需要构造实例,用newInstance()方法,
eg Class c = XX.class;
Object obj = c.newInstance();
1)这种方式声明(Class c 非泛型方式)注意newInstance()返回的是Object,需要向下转型;
2)newInstance()方法需要类中声明了默认无参数构造方法;
3)Class<XXX> x = XXX.class; 通过泛型对类型有限制,x的引用到时候只能指向XXX的类对象了,那么x.newInstance();就不用向下转型了,返回的就是XXX的实例;这种方式最常用。Class<?> c基本等价于 Class c 就是不限制类型。
看一个小例子
/**
*《think in Java 》 p321
*/
class CountedNumber{
private static long counter;//初始化 为0
private final long id = counter++;
public String toString(){
return Long.toString(id);
}
}
class FieldList<T>{
//类对象的成员
private Class<T> type;
public FieldList(Class<T> clz){
this.type = clz;
}
public List<T> create(int n){
List<T> list = new ArrayList<T>();
try{
for(int i = 0;i <n; i++ ){
//通过类对象的引用构造实例
list.add(type.newInstance());
}
}catch(Exception e){
throw new RuntimeException();
}
return list;
}
}
//Test
public class Reflect {
public static void main(String[] args) {
FieldList<CountedNumber> fl =
new FieldList<CountedNumber>(CountedNumber.class);
System.out.println(fl.create(10));
}
}