需求:
有一个类,包含很多以test为开头的方法。代码执行这个类中以test为开头的方法;这个类有无参数构造器,这些类有无参数构造器,这些方法都是无返回数,非静态方法;
分析:
1.不知道类名;
2:不知道方法名
反射 必须使用动态的反射API实现上述功能
反射AIP
动态加载类
在运行期间,根据动态的给定的类名,动态加载类到方法区;
api 代码:
Class.forName(类名);
案例
Scanner in=new Scanner(System.in);
String className=in.nextLine();
Class cls=Class.forName(className);
cls.getName();//获取类名
/**
* 将动态的加载类到方法区
* @author liulin1
*
*/
public class demo01 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Scanner in=new Scanner(System.in);
System.out.println("输入类名:");
String className=in.nextLine();
//利用反射API,动态加载类到方法区
Class cls=Class.forName(className);
//cls 引用对象就是通向方法区的通道
//cls 可以获取一切方法区中的信息
System.out.println(cls.getName());
//动态调用类信息的无参构造器
//创建对象,在不知道类名时候使用;
Object obj=cls.newInstance();
System.out.println(obj);
}
}
package demo;
public class Foo {
}
使用反射API在运行期间处理注解
package demo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Scanner;
/**
* 动态获取类中的方法信息
* @author liulin1
*
*/
public class demo02 {
public static void main(String[] args) throws ClassNotFoundException{
Scanner in=new Scanner(System.in);
System.out.println("请输入类名:");
String className=in.nextLine();
//动态加载类
Class cls=Class.forName(className);
//动态获取类的方法信息
Method[] methods=cls.getDeclaredMethods();
//methods数组中的每个元素,都代表一个方法信息
for(Method m:methods){
//m代码每个方法信息
//"^test*$"
String regex="^test.*$";
String name=m.getName();
//找到了test开头的无参数构造方法
if(name.matches(regex)&&m.getParameterTypes().length==0){
System.out.println(m);//public void demo.Foo.atest()
}
//被注释的方法
Annotation[] ans=m.getAnnotations();
for(Annotation a:ans){
System.out.println("注解:"+Arrays.toString(ans));
}
}
//类中所有属性
Field[] fields=cls.getDeclaredFields();
for(Field f:fields){
System.out.println(f);
}
}
}
package demo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
public class Foo {
private String a;
private String b;
private String c;
private String e;
private String f;
private String g;
@MyAnnotation
public void test(String a){
System.out.println("Hello");
}
public void test1(String a){
System.out.println("test1....");
}
public void test2(String a){
System.out.println("test2....");
}
public void test3(String a){
System.out.println("test3....");
}
public void test4(){
System.out.println("test4....");
}
public void test5(){
System.out.println("test5....");
}
public void test6(){
System.out.println("test6....");
}
public void atest(){
System.out.println("atest....");
}
public void btest(){
System.out.println("btest....");
}
public void ctest(){
System.out.println("ctest....");
}
public void dtest(){
System.out.println("dtest....");
}
@MyAnnotation
public void etest(){
System.out.println("etest....");
}
}
使用反射API 调用方法
Method m=—
1. 对象上必须 包含m方法!
- 否则会出现运行异常!
2. 方法必须包含相应的参数
- 否则也会出现异常
m.invoke(对象,参数列表)
//再对象上执行m方法,向方法传递参数(参数列表)
/**
*动态调用 方法
* @author liulin1
*
*/
public class demo03 {
public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
Scanner in=new Scanner(System.in);
System.out.println("请输入类名:");
String className=in.nextLine();
//动态加载类
Class cls=Class.forName(className);
String str="你好";
Object obj=cls.newInstance();
Method[] methods=cls.getDeclaredMethods();
for(Method m:methods){
//找到了test来头的无参数方法
if(m.getName().startsWith("test")&&m.getParameterTypes().length==0){
System.out.println(m);
Object val=m.invoke(obj);//invoke返回结果为m方法的返回结果
Sysytem.out.println(val);
}
}
}
}
配置xml文件如何初始化各类对象
加载dom4j-1.6.jar
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ApplicationCantext {
private Map<String,Object> beans;
public ApplicationCantext(String xml) throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException{
//初始化Bean容器,根据配置文件,创建每个对象
SAXReader reader=new SAXReader();
InputStream in=
ApplicationCantext.class.getClassLoader().getResourceAsStream(xml);
Document doc=reader.read(in);
Element root=doc.getRootElement();
List<Element> els=root.elements();
for(Element e:els){
//e就是bena元素
String id=e.attributeValue("id");
String className=e.attributeValue("class");
Class cls=Class.forName(className);
Object obj=cls.newInstance();
//将创建的对象保存到beans集合
beans.put(id, obj);
}
}
public Object getBean(String id){
//返回容器中某个bean对象
return beans.get(id);
}
}