在程序运行期间,Java运行系统始终为所有的对象维护一个被称为运行时类型标识,这个信息跟踪着每个对象所属的类。虚拟机利用运行时的类型信息选择相应的方法执行。保存这些信息的类被称为Class,一个Class对象表示一个特定类的属性
能够分析类能力的程序称为反射:
反射可以:
1.运行时分析类的能力‘
2.在运行时查看对象 e.g 编写一个toString对象供所有类使用
3.实现通用的数组操作代码
常用的方法:
Field[] getFields()
//返回一个包含Field对象的数组,这些对象记录所有的公有成员变量
Field[] getDeclaredFields()
//也返回一个包含Field对象的数组,不同的是这些对象记录的是所有的成员变量信息
//如果类中没有成员变量or Class对象描述的是基本类型或数组类型,这些方法返回一个长度为0的数组。
Method[] getMethods()//返回包含Method对象的数组,getMethods()返回所有的共有方法
Method[] getDeclaredMethods()//返回全部方法,但不包括由超类继承来的方法
Constructor[] getConstructors()//返回记录*所有公有构造器的Constructor对象数组
COnstructor[] getDeclaredConstructors()//返回记录所有构造器的Constructor对象数组
package reflection;
/**
* Class类,任何一个类都是Class类的实例对象,这个实例对象有三种表达方式
* @version 1.0 2016-8-31
* @author Administrator
*/
class Foo{
public void print(){
System.out.println("foo");
}
}
public class Test {
public static void main(){
Class c1=Foo.class; //1.任何一个类都存在一个隐含的静态成员变量class
Foo foo1=new Foo(); //2.已经知道该类的对象通过getClass()方法
Class c2=foo1.getClass();
System.out.println(c1==c2); //c1,c2表示Foo类的类类型,一个类只可能是Class的一个实例对象
Class c3=null; //3.Class.forName()手工地加载其他的类
try {
c3=Class.forName("reflection.test");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c2==c3);
try { //通过newInstance方法初始化新创建的对象
Foo foo=(Foo) c1.newInstance();
foo.print();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
下面是一个完整的实例,打印出类的成员信息
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
* 使用反射打印出一个类的基本属性
* @version 1.0 2016-08-30
* @author Administrator
*
*/
public class ReflectionTest {
/*
* 打印一个类的所有构造器
*/
public static void printConstructors(Class cl)
{
Constructor[] constructors=cl.getDeclaredConstructors();
for(Constructor c:constructors){
String name=c.getName();
System.out.println(" ");
String modifiers=Modifier.toString(c.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
System.out.println(name+"(");
Class[] paramTypes=c.getParameterTypes();
for(int j=0;j<paramTypes.length;j++)
{
if(j>0)
System.out.print(", ");
System.out.println(paramTypes[j].getName());
}
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(" ");
String modifiers=Modifier.toString(m.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
System.out.println(reType.getName()+" "+name+"(");
Class[] paramTypes=m.getParameterTypes();
for(int j=0;j<paramTypes.length;j++)
{
if(j>0)
System.out.print(", ");
System.out.println(paramTypes[j].getName());
}
System.out.println(")");
}
}
/*
* 打印一个类的所有域
*
*/
public static void printFields(Class cl)
{
Field[] fields=cl.getDeclaredFields();
for (Field field : fields) {
Class type=field.getType();
String name=field.getName();
System.out.println(" ");
String modifiers=Modifier.toString(field.getModifiers());
if(modifiers.length()>0)
System.out.println(type.getName()+" "+name+";");
}
}
public static void main(String[] args)
{
String name;
if(args.length>0)
name=args[0];
else
{
Scanner in=new Scanner(System.in);
System.out.println("Enter class name:");
name=in.next();
try{
Class cl =Class.forName(name);
Class supercl=cl.getSuperclass();
String modifiers=Modifier.toString(cl.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+"");
System.out.println("class "+name);
if(supercl !=null && supercl !=Object.class)
System.out.println("extends "+supercl.getName());
System.out.println("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
}catch(ClassNotFoundException e)
{
e.printStackTrace();
}
int status=0;
System.exit(status);
}
}
}