什么是反射

可以简单的理解为将类的各个组成部分封装为其他对象,这就是反射机制 比如ide(集成开发工具)里面的代码提示功能,判断某个包是否含有某个类,属性,变量等;或者你接手某个同事的代码时,可以用反射判断该同事某个方法是否写了的。

常用方法

得先知道用法,才能写代码

* 获取Class对象的方式:
		1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
			* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
		2. 类名.class:通过类名的属性class获取
			* 多用于参数的传递
		3. 对象.getClass():getClass()方法在Object类中定义着。
			* 多用于对象的获取字节码的方式

		* 注意:
			同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。


	* Class对象功能:
		* 获取功能:
			1. 获取成员变量们
				* Field[] getFields() :获取所有public修饰的成员变量
				* Field getField(String name)   获取指定名称的 public修饰的成员变量

				* Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
				* Field getDeclaredField(String name)  
			2. 获取构造方法们
				* Constructor<?>[] getConstructors()  
				* Constructor<T> getConstructor(类<?>... parameterTypes)  

				* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  
				* Constructor<?>[] getDeclaredConstructors()  
			3. 获取成员方法们:
				* Method[] getMethods()  
				* Method getMethod(String name, 类<?>... parameterTypes)  

				* Method[] getDeclaredMethods()  
				* Method getDeclaredMethod(String name, 类<?>... parameterTypes)  

			4. 获取全类名	
				* String getName()  


	* Field:成员变量
		* 操作:
			1. 设置值
				* void set(Object obj, Object value)  
			2. 获取值
				* get(Object obj) 

			3. 忽略访问权限修饰符的安全检查
				* setAccessible(true):暴力反射



	* Constructor:构造方法
		* 创建对象:
			* T newInstance(Object... initargs)  

			* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法


	* Method:方法对象
		* 执行方法:
			* Object invoke(Object obj, Object... args)  

		* 获取方法名称:
			* String getName:获取方法名

方法的使用

先获取Class对象,再对调用该对象的变量,方法

先看下目录

java 反射带参数构造方法 java反射的使用_成员变量

获取Class对象

package model;

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {

        //获取Class对象

        //根据全类名获取
        Class user = Class.forName("model.User");
        System.out.println(user);//class model.User

        //类名的属性class获取
        Class user2 = User.class;
        System.out.println(user2);//class model.User


        //根据对象获取
        User user3 = new User();
        Class user4 = user3.getClass();
        System.out.println(user4);//class model.User

        System.out.println(user == user2);//true
        System.out.println(user == user4);//true
        System.out.println(user2 == user4);//true
		
		//用"=="表示 判断的是对象的内存地址,这里判断是不是同一个对象作用

    }
}

java 反射带参数构造方法 java反射的使用_System_02

获取变量

package model;

import java.lang.reflect.Field;

public class ReflectDemo2 {
    public static void main(String[] args) throws Exception {
        //获取成员变量

        Class person = Person.class;
        Person pObj = new Person();

        //获取public成员变量
        Field name = person.getField("name");
        System.out.println(name);//public java.lang.String model.Person.name
        name.set(pObj,"张三");
//        System.out.println(pObj.getName()); 张三
        System.out.println(name.get(pObj) );//张三

        System.out.println("================");

        Field[] fields = person.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("================");


        //无视修饰符成员变量
        Field card = person.getDeclaredField("card");
        System.out.println(card);//private java.lang.String model.Person.card
        card.setAccessible(true);//暴力反射
        card.set(pObj,"身份证号码");
        System.out.println(card.get(pObj));

        System.out.println("================");

        Field[] declaredFields = person.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }


    }
}

java 反射带参数构造方法 java反射的使用_成员变量_03

获取构造方法

这里用的是Person类做测试,先看下Person的代码

Person类的代码

package model;

public class Person {
    public String name;
    public Integer age;
    private String card;
    private  String address;

    public static void main(String[] args) {
        String phone = "12345678901";
        call(phone);
    }
    public Person(){
        //System.out.println("无参构造被执行了");
    }

    public Person(String name,Integer age){
        //System.out.println("name:"+name+",age:"+age);
    }

    public static void call(String phone) {
        System.out.println("给"+phone+"打电话");
    }

    private static void info() {
        System.out.println("这是个私有方法");
    }

    public String getCard() {
        return card;
    }

    public void setCard(String card) {
        this.card = card;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", card='" + card + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

演示的代码

package model;

import java.lang.reflect.Constructor;

public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {
        Class personClass = Person.class;

        //获取无参构造方法
        Constructor constructor = personClass.getConstructor();
        System.out.println(constructor);

        //实例化无参构造
        Object o = constructor.newInstance();//Person o = new Person();
        System.out.println(o);

        System.out.println("=============");

        //获取无参构造方法
        Object o1 = personClass.newInstance();//Person o1 = new Person();
        System.out.println(o1);

        System.out.println("=============");

        //获取所有构造方法
        Constructor[] constructors = personClass.getConstructors();
        for (Constructor constructor1 : constructors) {
            System.out.println(constructor1);
        }

        System.out.println("=============");

        //获取有参构造方法
        Constructor constructor1 = personClass.getConstructor(String.class, Integer.class);
        Object o2 = constructor1.newInstance("张三", 22);//Person o1 = new Person("张三", 22);
    }
}

java 反射带参数构造方法 java反射的使用_System_04

获取成员方法

package model;

import java.lang.reflect.Method;

public class ReflectDemo4 {
    public static void main(String[] args) throws Exception{
        Class<Person> personClass = Person.class;
        Person p = new Person();

        //获取所有public方法(包括继承的方法)
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("==========");

        //获取所有员方法
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        System.out.println("==========");

        Method call = personClass.getMethod("call",String.class);//public static void model.Person.call(java.lang.String)
        Object invoke = call.invoke(p,"12345678901");//call(""12345678901");

        System.out.println("==========");

        Method info = personClass.getDeclaredMethod("info");
        info.setAccessible(true);//要想调用私有方法要暴力反射
        info.invoke(p);


    }
}

java 反射带参数构造方法 java反射的使用_反射_05