反射

需求:
有一个类,包含很多以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);
    }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值