Java反射机制概述及应用

反射机制

一、反射概述:

反射就是把java类中的各种成为映射成一个个的java对象; java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

二、获得类模板对象的三种方式

1.类名.class属性

Class cls1 = Person.class;

2.对象.getClass();

``Class cls2 = new Person().getClass();

3.使用Class的静态方法forName(完整类名)加载此类,并得到该类的类模板对象

Class cls3 = Class.forName("com.wenlong.Person");
第三种方法除了能得到类模板对象还能加载此类。

四、Class类的常用方法

1.创建对象

new Instance():创建此Class对象所表示的类的一个新实例。

2.获取字段

getFlied(String name):返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共字段;
getFlieds():返回一个Field对象,它反映此Class对象所表示的类或接口的所有公共字段;
getDeclaredField(String name):返回一个Field对象,它反映此Class对象所表示的类或接口的指定已声明字段;
getDeclaredFields:返回一个Field对象,它反映此Class对象所表示的类或接口的指定所有字段;

3.获取方法

getMethod(String name,,Class<?>... parameterTypes):返回一个Method对象,它反映此Class对象所表示的类或接口的指定公共成员方法。
此外还有getMethods(),getDeclaredMethod(String name,Class<?>... parameterTypes),getDeclaredMethods()方法 用法与Flied相似。

4.获取构造器

getConstructor(Class<?>... parameterTypes):返回一个Constructor对象,它反映此Class对象所表示类的指定公共构造方法,当然还有getConstructors()等其他三个方法。

五、Method对象:

1.常用方法:

invoke(Object obj,Object... args):对带有指定参数的指定对象调用由此Method对象表示的底层方法。

2.示例代码:
Class cls = Person.class;
//此时m1指向的是Person类的方法名是showName,参数列表是String的这个方法
Method method = cls.getMethod("showName",String.class);
//创建cls对象所表示类的一个实例
Object obj = cls.newInstance();
//调用obj中得到的method指定的方法showName带String参数的方法
method.invoke(obj,"zs");

六、Constructor对象:描述类中的某一个构造器

如果要调用类中带参的构造器来创建对象,就要用Constructor对象来描述带参的构造器,再通过该对象的newInstance方法得到一个类的对象。

示例代码
Class cls = new Person().getClass();
//获取所有公共构造方法
Constructor[] constructor = cls.getConstructors();
//获取指定公共构造方法
Constructor constructor = cls.getConstructor(String.class);
//指定有参构造器创建对象
Object obj = constructor.newInstance("abc");

七、反射方法的使用--通过反射运行配置文件内容

创建student类:

public class Student {  
    public void show(){  
        System.out.println("is show()");  
    }  
}

配置文件(pro.txt):

className = cn.reflect.Student  
methodName = show

测试类:

package com.reflect.configFile;
import java.io.FileInputStream;
import java.io.FileNotFoundException;  
import java.io.FileReader;  
import java.io.IOException;  
import java.lang.reflect.Method;  
import java.util.Properties;  
  
/* 
 * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改 
 * 我们只需要将新类发送给客户端,并修改配置文件即可 
 */  
public class TestConfigFile {
	 public static void main(String[] args) throws Exception {  
	        //通过反射获取Class对象  
	        Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"  
	        //2获取show()方法  
	        Method m = stuClass.getMethod(getValue("methodName"));//show  
	        //3.调用show()方法  
	        m.invoke(stuClass.newInstance());  
	          
	    }  
	      
	    //此方法接收一个key,在配置文件中获取相应的value  
	    public static String getValue(String key) throws IOException{  
	        Properties pro = new Properties();//获取配置文件的对象  
	        FileReader in = new FileReader("pro.propertities");//获取输入流  
	        pro.load(in);//将流加载到配置文件对象中  
	        in.close();  
	        return pro.getProperty(key);//返回根据key获取的value值  
	    }  
}

当我们升级这个系统时,不要Student类,而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动 要替换的student2类:

public class Student2 {  
    public void show2(){  
        System.out.println("is show2()");  
    }  
}

配置文件更改为:

className = cn.reflect.Student2 
methodName = show2

八、反射的使用--越过泛型检查

代码示例:

public class CrossGenericity{
    /*通过反射越过泛型检查
     *例题:像一个String泛型的集合添加一个Integer类型的值;
     */
     public static void main(String[] args) throws Exception{  
        ArrayList<String> strList = new ArrayList<>();  
        strList.add("aaa");  
        strList.add("bbb");
        //得到strList的字节码对象
        Class cls = strList.getClass();
        //获取add方法
        Method method = cls.getMethod("add",Object.class);
        //调用add方法
        method.invoke(cls,10);
        //遍历集合  
        for(Object obj : strList){  
            System.out.println(obj);  
        } 
}
理解反射的机制是理解动态代理原理的基础,希望今天整理的内容对大家有所帮助
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值