java反射

1.什么是反射

反射就是动态的加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都可以知道这个类的任意方法和属性;对于一个对象,可以调用这个对象的任意方法和属性。这种动态的获取信息以及调用对象方法的功能称之为java的反射机制。

2.反射的优缺点

2.1优点
反射提高了程序的灵活性和扩展性,在底层框架中用的比较多,比如Spring等。但是,在平常业务开发的层面用的比较少,还是少用吧。
2.2缺点
反射性能不那么好,耗时。
假如我们进行如下操作:创建一个对象的实例,然后赋值并取值。通过常规的new对象,set设置值,get取值的办法,整个过程耗时会很短。与之相比,通过反射的方法拿到实例,在进行赋值取值的操作,会更耗时,性能要差不少。

3.反射的实现

具体说明都会写在代码的注释里,这里就不再说什么了。

3.1获取Class对象的三种方法

首先创建一个实体类Person,定义一些基本的属性和方法,代码略。
然后是获取Person的Class对象的三种方法:

public class FanShe {

    public static void main(String[] args) throws ClassNotFoundException {

        //1.通过Class对象的forName(全类名)静态方法获取;全类名=包名.类名
        Class<Person> clazz = (Class<Person>) Class.forName("Person");

        //2.通过类名.class获取
        Class<Person> clazz2 = Person.class;

        //3.通过对象的getClass()方法获取
        Person person = new Person();
        Class<Person> clazz3 = (Class<Person>) person.getClass();
        
    }
    
}

3.2通过Class对象获取成员变量、构造方法、成员方法

简要说明:
get方法特点:带s的方法表示获取获取多个成员/构造,不带s的方法表示获取指定某个成员/构造;带Declared的方法表示获取任意类型的成员/构造,不带Declared的方法表示获取public修饰的成员/构造。

3.2.1. 获取成员变量

clazz.getFields() -> 获取所有public修饰的成员变量
clazz.getField(String name) -> 获取一个指定名称的 public修饰的成员变量
clazz.getDeclaredFields() -> 获取所有的任意修饰符类型成员变量
clazz.getDeclaredField(String name) -> 获取任意修饰符类型指定名称的成员变量

 Field field = clazz.getField("age");                	   	      //获取一个指定名称的public修饰的成员变量
        
        Field[] fields = clazz.getFields();                           //获取所有public修饰的成员变量
        
        Field field1 = clazz.getDeclaredField("name");    	      //获取一个指定名称的任意成员变量
       
        Field[] fields1 = clazz.getDeclaredFields();         	      //获取所有的任意修饰符修饰的成员变量

3.2.2.获取构造方法

clazz.getConstructors() -> 获取所有public修饰的构造方法
clazz.getConstructor(Class<?>… parameterTypes) -> 获取指定参数类型的public类型的构造
clazz. getDeclaredConstructor(Class<?>… parameterTypes) -> 获取指定参数类型的任意类型的构造
clazz.getDeclaredConstructors() -> 获取任意类型所有的构造方法
代码和上面类似,就不再重写了。

3.2.3 获取成员方法

clazz.getMethods() -> 获取所有public修饰的方法(可以获取父类的public修饰的方法)
clazz.getMethod(String name, Class<?>… parameterTypes) -> 获取一个指定名称指定参数类型的public类型成员方法
clazz.getDeclaredMethods() -> 获取任意类型所有的成员方法
clazz.getDeclaredMethod(String Class, 类<?>… parameterTypes) -> 获取一个指定名称指定参数类型的任意类型成员方法
代码:同上

3.3操作成员变量、构造方法、成员方法

3.3.1 操作成员变量:获取值以及设置值

field.get(Object obj); -> 表示获取哪个对象的field成员变量值;
field.set(Object obj, Object value); -> 表示设置obj对象的field成员变量值为value;

注意:如果成员变量是非public修饰的,那么必须要在get和set之前取消访问检查:field.setAccessible(true);

field1.setAccessible(true);                         //取消检查
        Person person1 = clazz.newInstance();               //获取实例
        field1.set(person1, "小明");                     //设置属性值
        System.out.println(field1.get(person1));            //获取属性值

3.3.2 操作构造方法:创建对象
Object obj=constructor.newInstance(Object…param); -> 创建对象,并且传递构造需要的参数
Object obj=Class对象.newInstance(); -> 执行的是空参构造

注意:如果构造方法是非public修饰的,那么必须要在newInstance之前取消访问:constructor.setAccessible(true);

3.3.3. 操作成员方法:调用方法
method.invoke(Object obj, Object… args); -> 执行obj对象身上的method方法并给方法传递的参数值为args。

Method method = clazz.getMethod("get");
        method.invoke(person1);					//get方法没有参数 ,所以参数部分不用填或者写null都可以

注意:如果成员方法是非public修饰的,那么必须要在invoke之前取消访问检查:method.setAccessible(true);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值