Methodmethods[] = clazz.getDeclaredMethods();
for(Method meth : methods)
System.out.println(meth.getName()+meth.getReturnType());
//3、2从Class中取出对应类的某个方法,并输出其信息
Methodmethod = clazz.getMethod('hashCode', new Class[] {});
System.out.println(method.getName()+ method.getReturnType());
//4、1 从Class中取出对应类的全部构造方法,并输出其信息
Constructorconstructors[] = clazz.getDeclaredConstructors();
for(Constructor cons : constructors) {
System.out.print(cons.getModifiers()+ cons.getName());
for(Type type : cons.getParameterTypes())
System.out.println(type+ ' ');
}
//4、2 从Class中取出对应类的某个构造方法,并输出其信息
Constructorcons = clazz.getDeclaredConstructor(new Class[]
{char[].class, int.class, int.class });
System.out.print(cons.getModifiers()+ cons.getName());
for(Type type : cons.getParameterTypes())
System.out.print(type+ ' ');
//5、 从Class中取出对应类所在包、类的完整名、简名、父类等信息
System.out.println(clazz.getPackage().getName());
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
System.out.println(clazz.getSuperclass());
}
3. 取得Class实例的方法
Class Object的诞生管道 |
实例 |
运用getClass() 注:每个类都从Object类继承这个方法 |
String str= 'abc'; Class c1=str.getClass(); |
运用.class语法 |
Class c2=String.class; Class c3=java.awt.Button.class Class c4=int.class |
运用static method Class.forName() (最常被使用) |
Class c5=Class.forName('java.lang.String'); (参数必须是完整类名,包括包名) |
运用基本数据类型的包装类的TYPE语法 |
Class c6=Integer.TYPE; Class c7=Double.TYPE; |
三、反射的具体使用Class对象可以获得该类里的成分包括构造器(由Constructor对象表示)、方法(由Method对象表示)、属性(由Field对象表示),这三个类都定义在java.lang.reflect包下,程序可以通过Constructor对象来调用对应的构造器创建对象实例,可以通过Method对象来执行对应的方法,通过Field对象直接访问或修改对象的属性值。
1. 运行时生成类的实例通过反射生成对象有如下两种方式:
(1)通过Class的newInstance()方法使用Class对象的newInstance()方法来创建该Class对象对应类的实例,这种方法要求该Class对象的对应类有无参构造方法,而执行newInstance()实际上就是执行无参构造方法来创建该类的实例。
//相当于语句:Student stu=new Student();
Objectobj=Class.forName('cn.bsw.reflection.Student').newInstance();
此种方法比较常用,因为在很多JavaEE框架中都需要根据配置文件信息来创建Java对象,从配置文件读取的只是某个类的字符串类名,程序就需要根据该字符串来创建对应的实例,此时必须使用反射。
(2)通过Constructor的newInstance()方法先使用Class对象获取指定的Constructor对象,在调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例。通过这种方法可以选择使用某个类的指定构造方法来创建实例。
//针对有参构造方法,相当于:Student stu=new Student('lkl',32,56.5f);
Classclazz=Class.forName('cn.bsw.reflection.Student');
Constructorcons=clazz.getConstructor(new Class[]
{String.class,int.class,float.class});
Objectobj=cons.newInstance(new Object[]{'lkl',32,56.5f});
//针对无参构造方法,相当于语句:Student stu=new Student();
obj=clazz.getConstructor(newClass[]{}).newInstance(new Object[]{});
obj=clazz.getConstructor().newInstance();
System.out.println(obj);
从以上代码中可以看出,采用第二种方法创建类的实例需要如下三个步骤:
1)获取该类的Class对象。
2)利用Class对象的getConstructor()方法获取指定的构造器(准备一个Class[]作为该方法的参数类型)。
3)调用Constructor的newInstance()方法来创建相应类的对象(准备一个Object[] 作为该方法的实参值)。
2. 运行时变更与调用field值通过Class对象的getFields()或者getField()方法可以获得该类所包括的全部Field属性或指定Field属性。Field提供了以下两组方法来访问属性。
ØgetXxx(Object obj):获取obj对象该Field的属性值。此处的Xxx对应8个基本数据类型,如果该属性类型是引用类型则直接使用get(Object obj)。
ØsetXxx(Object obj,Xxxval):将obj对象的该Field设置成val值。此处的Xxx对应8个基本数据类型,如果该属性类型是引用类型则直接使用set(Object obj,Object val)。
ØsetAccessible(Boolean flag):Field类从父类AccessibleObject中继承的方法。若flag为true,则取消属性的访问权限控制,即使private属性也可以进行访问;若flag为false,则取消属性的访问权限控制,private属性也可以进行访问。
Classclazz=Class.forName('cn.bsw.reflection.Student'); Objectobj=clazz.newInstance();
//调用getDeclaredField('name')方法取得name属性对应的Field对象。
Fieldf=clazz.getDeclaredField('name');
//取消属性的访问权限控制,即使private属性也可以进行访问。
f.setAccessible(true);
//调用get()方法获取并输出对应属性值。
System.out.println(f.get(obj));
//调用set()方法给对应属性赋值。
f.set(obj,'lkl');
//调用get()方法获取并输出对应属性修改后的值。
System.out.println(f.get(obj));
3. 运行时调用method通过Class对象的getMethods()或者getMethod()方法可以获得该类所包括的全部方法或指定方法,这两个方法的返回值是Method[]或者Method。每个Method对象对应一个方法,获得Method对象后,就可以调用它的invoke()方法来调用对应方法。
ØObject invoke(Objectobj,Object [] args):obj代表当前方法所属的对象的名字,args代表当前方法的参数列表,返回值Object是当前方法的返回值,即执行当前方法的结果。
public classInvokeMethod {
2/3 首页 上一页 1 2 3 下一页 尾页 |