在程序运行期间,java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。虚拟机利用运行时的类型信息选择相应的方法执行。
保存这些信息的类称为Class,Object类中的getClass()方法将会返回一个Class类型的实例,如同用一个Employee对象表示一个特定的雇员属性一样,一个Class对象将表示一个特定类的属性。
最常用的Class方法是getName()将返回类的名字 如果类在包里,包的名字也作为类名的一部分。
Employee em=new Employee("liyu",13);
Class c=em.getClass();
String name=c.getName();
静态方法forName()获得类名对应的Class对象。
String className="com.Employee" //com包中的Employee类
Class cl=Class.forName(className)
这个方法只有在className是类名或者接口名时才能够执行。
获得Class类对象的三种方法:
1. Employee em=new Employee("liyu",13);
Class c1=em.getClass();
2. String className="com.Employee" //com包中的Employee类
Class c2=Class.forName(className);
3. Class c3=com.Employee.Class;
可以利用==实现两个类对象比较的操作
System.out.println(c1.equals(c2));
System.out.println(c1==c2);
均返回true
因为Class类中的equals方法为:
public boolean equals(Object obj) {
return (this == obj);
}
Class类中的newInstance()方法可以用来快速地创建一个类的实例
Employee em=new Employee("liyu",13);
Class c=em.getClass();
Object emo=c.newInstance();
Employee emc=(Employee)emo;
newInstance()方法调用默认的构造器(没有参数的构造器)初始化新的创建对象。如果这个类没有默认的构造器会报异常。
如果需要以这种方式向希望按名称创建的类的构造器提供参数,就必须使用Constructor类中的newInstance方法。
Employee em=new Employee("liyu",13);
Class c=em.getClass();
Constructor[] con=c.getConstructors();
System.out.println(con.length );
Employee emcon=(Employee)con[1].newInstance("lis",123);
System.out.println(emcon.getName());
java.lang.reflect包括三个类:
- 1.Field 2.Method 3.Constructor
- 共有方法:getName():返回项目的名称
- 共有方法:getModifiers():返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用状况
- java.lang.reflect包中的Modifier类的静态方法可以分析getModifiers()返回的整型数值
- 可以使用Modifier类中的isPublic isPrivate或isFinal判断方法或者构造器是否是public、private或final
- 我们需要做的就是调用Modifier类的相应方法,并对返回的整型数值进行分析,还可以利用Modifier.toString()方法将修饰符打印出来
- Field类特有方法getType():返回描述域所属类型的Class对象
- Method类和Constructor类有能够报告参数类型的方法
- Mehtod类还有一个可以报告返回类型的方法
java.lang.Class: - Class类中的getFields、getMethods和getConstructors方法将分别返回类提供的pulbic域、方法和构造器数组,其中包括超类的公有成员。
- Class类中的getDeclaredFields、getDeclaredMethods和getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类成员。
可以分析java解释器能够加载的任何类,而不仅仅是编译程序时可以使用的类。
public static void printConstructors(Class cl) {
Constructor []constructors=cl.getDeclaredConstructors();
System.out.println("构造器数组长度:"+constructors.length);
for(Constructor c:constructors) {
//构造器的名称
String name=c.getName();
System.out.println("构造器名字:"+name);
//构造器修饰符 public or private or默认
int f=c.getModifiers();
String modifiers=Modifier.toString(f);
if(modifiers.length()>0)
System.out.println("构造器修饰符:"+modifiers);
//构造器的参数
Class[] paramType=c.getParameterTypes();
System.out.print("构造器的参数:");
for(int i=0;i<paramType.length;i++) {
System.out.print(paramType[i]+",");
}
System.out.println();
}
}
public static void printMethods(Class cl) {
Method[] methods=cl.getDeclaredMethods();
for(Method m:methods) {
Class reType=m.getReturnType();
String name=m.getName();
System.out.println("方法类型名:"+reType.getName());
System.out.println("方法名:"+name);
String modifiers=Modifier.toString(m.getModifiers());
if(modifiers.length()>0)
System.out.println("方法修饰符:"+modifiers);
Class[] parameterTypes=m.getParameterTypes();
System.out.print("方法参数列表:");
for(int i=0;i<parameterTypes.length;i++)
System.out.print(parameterTypes[i]+",");
System.out.println();
}
}
public static void printFields(Class cl) {
Field[] fields=cl.getDeclaredFields();
for(Field f:fields) {
Class type=f.getType();
System.out.println("域类型:"+type);
String name=f.getName();
System.out.println("域名:"+name);
String modifiers=Modifier.toString(f.getModifiers());
if(modifiers.length()>0)
System.out.println("域修饰符:"+modifiers);
}
}