您的位置:首页 > 其它

第14章 类型信息

2013-05-03 23:58 253 查看

14.2 Class对象

Class类:java.lang.Class 一个继承自java.lang.Object的模板类,RTTI的核心。每一个类都有一个Class类的对象,比如一个Teacher类,相应的就有一个Teacher的Class对象(程序启动前保存在Teacher.class文件中)。

所有的类都是在对其第一次使用时,动态加载到JVM中的。Java程序在它开始运行前并非被完全加载,其各个部分是在必须时才加载的。

比如对于一个Teacher类,类加载器首先检查Tearcher的Class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件(Tearcher.class)。一但Tearcher的Class对象被载入内存,他就被用来创建这个类的所有对象。

有两个方法可以获得某一个类的Class对象:

Class.forName()

Object.getClass()

类字面常量。这种形式与前两者有所不同,在于并不会初始化该Class对象。初始化被延迟到了对静态方法或者非常数静态域的首次引用时。

import static java.lang.System.out;
class Teacher {
Teacher(String name){this.name = name;}
public String getName(){return name;}
private String name = "";
}

public class Test {
public static void main(String args[]){
try {
Class teacherClass = Class.forName("Teacher");
out.println(teacherClass);
out.println(teacherClass.getCanonicalName());
out.println(teacherClass.getConstructors());
out.println(teacherClass.isAnnotation());
out.println(teacherClass.getClassLoader());
out.println(teacherClass.getDeclaredFields()[0]);
out.println(teacherClass.getDeclaredMethods()[0]);

Teacher t = new Teacher("Peter");
out.println(t.getClass());

Class teacherClass2 = Teacher.class;
out.println(teacherClass2);
}
catch (Exception e) {
e.printStackTrace();
}
}
}/*Output:
class Teacher
Teacher
[Ljava.lang.reflect.Constructor;@14318bb
false
sun.misc.Launcher$AppClassLoader@addbf1
private java.lang.String Teacher.name
public java.lang.String Teacher.getName()
class Teacher
class Teacher
*/


泛化的Class引用,下面这段代码初次读的时候没搞明白什么意思。

import java.util.*;
class CountedInteger{
private static long counter;
private final long id = counter++;
public String toString() {return Long.toString(id);}
}

public class FilledList<T> {
private Class<T> type;
public FilledList(Class<T> type){this.type=type;}
public List<T> create(int nElements){
List<T> l = new ArrayList<T>();
try{
for(int i = 0; i < nElements; ++i)
l.add(type.newInstance());
}
catch(Exception e){
throw new RuntimeException(e);
}
return l;
}
public static void main(String args[]){
FilledList<CountedInteger> fl = new FilledList<CountedInteger>(CountedInteger.class);
System.out.println(fl.create(15));
}
}/*
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
*/


注意:如果想要用Class.newIntance()方法的话,那么这个Class必须有一个默认构造器。

14.3 类型转换前先做检查

Java的三种RTTI形式:

1. 传统的类型转换,如(DeriveType)baseTypeObject;由RTTI确保了类型转换的正确性,如果执行一个错误的类型转换,就会抛出一个ClassCastException异常。

2. Class对象。(如前面介绍的)

3. instanceof

14.7 动态代理

http://www.techavalanche.com/2011/08/24/understanding-java-dynamic-proxy/

14.9 接口与类型信息

在反射面前,一切信息都无法隐藏。

java.lang.reflect.AccessibleObject接口定义了 setAccessible()方法可以修改访问权限。Constructor,Field和Method类都实现了这个接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: