JAVA反射机制介绍

反射:框架的灵魂设计

框架: 半成品软件。可以在框架的基础上进行软件的开发,简化编码。
反射:将类的各个组成部分封装为其他对象,这就是反射机制。
好处
1.在程序的运行过程中去操作这些对象。
2.可以解耦,提高程序的可扩展性。

获取Class类对象的三方式:
Source 源代码阶段
Class.forName(“全类名”) 包名+类名:将字节码文件加载进内存,返回Class对象。
* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
Class类对象阶段
类名.Class : 通过类名的属性class获取
* 多用于参数的传递
RunTime 运行是阶段
对象.getClass(): getClass()方法在Object 类中定义着
*多用于对象的一个获取字节码的方式

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

使用Class对象功能:
*获取功能:
1.获取成员变量们

Field[] getFields() :获取所有Public修饰的成员变量
Field getField(String name) :获取指定名称的public修饰的成员变量树
Field getDeclaredField(String name):获取指定的成员变量  不考虑修饰符 
Field[] getDeclaredFields() 获取所有的成员变量  不考虑修饰符 
		

2.获取构造方法们

Constructor getConstructor(... parameterTypes) 
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。  
Constructor[] getConstructors() 
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象 
Constructor<T> getDeclaredConstructor(<?>... parameterTypes) 
返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。  
Constructor<?>[] getDeclaredConstructors()  
返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。 

3.获取成员方法们

Method getMethod(String name,<?>... parameterTypes) 
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。  
Method [] getMethods()  
Method  getDeclaredMethod(String name,... parameterTypes) 
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。  
Method []  getDeclaredMethods() 
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。  

4. 获取类名
String getName()

Field:成员变量

*1.设置值
	void set(Object obj,Object value)
*2.获取值
	get(Object obj)
*3.访问私有  忽略访问权限修饰符的安全检查
	dField.setAccessible(true);//暴力反射

Constructor
*创建对象

T newInstance(Object... initargs)  
	
如果空参构造方法,可以简化操作  Class对象的newInstance 方法
	
Method 方法对象
	执行对象
		Object invoke(Object obj,Object....args)
		
	获取方法名称:
		String getName //获取方法名	

案例:
需求:写一个“框架”,不能改变该类的任意代码前提下,帮助我们创建任意类的对象,并且执行其中任意的方法,
实现:
1. 配置文件
2. 反射
步骤:
1. 将需要创建对象的全类名和需要执行的方法定义在配置文件中
2. 在程序中加载读取配置文件
3. 使用发射技术来加载类文件进内存
4. 创建对象,
5. 执行方法

Person.java

package edgedo.pojo;

public class Person {

    private String name;
    private int age;

    public String a;
    public String a2;
    protected String b;
    String c;
    private String   d;



    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    public void eat(){
        System.out.println("eat eat eat eat ");
    }

    public void eat(String food){
        System.out.println("eat eat eat eat "+food);
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", a='" + a + '\'' +
                ", a2='" + a2 + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }
}

ReflectDemo.java

package edgedo.reflect;


import edgedo.pojo.Person;

public class ReflectDemo {


    /**
     * 获取Class类的三种方式
     * *获取Class类对象的三方式:
     1.Source  源代码阶段
     Class.forName(“全类名”) 包名+类名:将字节码文件加载进内存,返回Class对象。
     2. Class类对象阶段
     类名.Class  :  通过类名的属性class获取
     3. RunTime  运行是阶段
     对象.getClass():  getClass()方法在Object 类中定义着
     */

    public static void main(String[] args) throws Exception {
        //Class.forName.
       Class cls =  Class.forName("com.edgedo.pojo.Person");
        System.out.println(cls);

        //2.类名.Class
        Class cls2  = Person.class;
        System.out.println(cls2);

        //3.对象通过getClass()
        Person p = new Person();
        Class cls3  = p.getClass();
        System.out.println(cls3);


        //==比较两个对象
        System.out.println(cls==cls2);//true
        System.out.println(cls==cls3);//true
        System.out.println(cls2==cls3);//true
    }
}

ReflectDemo2

package edgedo.reflect;

import edgedo.pojo.Person;

import java.lang.reflect.Field;

public class ReflectDemo2 {

   /*1.获取成员变量们
			Field[] getFields()
            Field getField(String name)
            Field getDeclaredField(String name)
            Field[] getDeclaredFields()
*/
    public static void main(String[] args) throws Exception {
       //1.获取Person的Class对象
        Class<Person> personClass = Person.class;
        //Field[] getFields()
        Field[] fields = personClass.getFields();
        for(Field field:fields){
            System.out.println(field);
        }

        System.out.println("111");
        System.out.println("------");

        // Field getField(String name)
        Field a = personClass.getField("a");
//        System.out.println(a);
        //获取成员变量a的值
        Person p = new Person();
        a.set(p,"哈哈哈");//给哪一个对象传递什么数值

        Object value =  a.get(p);
        System.out.println(value);


       // Field[] getDeclaredFields()  获取所有的成员变量不考虑修饰符
        Field[] declFiields = personClass.getDeclaredFields();
        for(Field field:declFiields){
            System.out.println(field);
        }
        // Field getDeclaredField(String name)
        Field dField  = personClass.getDeclaredField("d");
        //访问私有  忽略访问权限修饰符的安全检查
        dField.setAccessible(true);//暴力反射
        Object dValue = dField.get(p);
        System.out.println(dValue);
    }
}

ReflectDemo3

package edgedo.reflect;


import edgedo.pojo.Person;

import java.lang.reflect.Constructor;

public class ReflectDemo3 {

   /*
            2.获取构造方法们
            Constructor getConstructor(类... parameterTypes)
            Constructor[] getConstructors()
            Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
            Constructor<?>[] getDeclaredConstructors()

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

            Method  getDeclaredMethod(String name, 类... parameterTypes)
            Method []  getDeclaredMethods()

*/
    public static void main(String[] args) throws Exception {
       //1.获取Person的Class对象
        Class<Person> personClass = Person.class;
        //构造方法
        Constructor constructor =  personClass.getConstructor(String.class,int.class);
        System.out.println(constructor);

        //创建对象
        Object person = constructor.newInstance("张三",16);
        System.out.println(person);
        System.out.println("----");
        Constructor constructor1 =  personClass.getConstructor();
        Object person1 = constructor1.newInstance();
        System.out.println(person1);

        System.out.println("----");
        //简化创造空参对象
        Object o  = personClass.newInstance();
        System.out.println(o);


    }
}

ReflectDemo4

package edgedo.reflect;


import edgedo.pojo.Person;

import java.lang.reflect.Method;

public class ReflectDemo4 {


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

        Method  getDeclaredMethod(String name, 类... parameterTypes)
        Method []  getDeclaredMethods()
*/
    public static void main(String[] args) throws Exception {
       //1.获取Person的Class对象
        Class<Person> personClass = Person.class;

        //获取指定名称的方法
        Method eatMethod = personClass.getMethod("eat");
        //创建对象
        Person person =new Person();
        //执行方法
        eatMethod.invoke(person);

        //获取有参的方法
        Method eatMethod2  = personClass.getMethod("eat",String.class);
        eatMethod2.invoke(person,"咖喱土豆");

        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method:methods){
            System.out.println(method);
            System.out.println("-----");
            System.out.println(method.getName());
        }


        //获取类名
        String className = personClass.getName();
        System.out.println(className);



    }
}

ReflectTest

package edgedo.reflect;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //可以创建任意类的对象  可以执行任意方法
        /*前提:不能改变该类的任意代码
        可以创建任意类的对象  可以执行任意方法*/

        //1.加载配置文件
            //1.1创建properties对象
        Properties pro= new Properties();
            //1.2 加载配置文件  转换为一个集合
            //1.2.1 获取class目录下的配置文件的目录
        ClassLoader classLoader =   ReflectTest.class.getClassLoader();
        InputStream inputStream =  classLoader.getResourceAsStream("pro.properties");
        pro.load(inputStream);

        //2. 获取配置文件中定义的数据
        String className =  pro.getProperty("className");
        String methodName =  pro.getProperty("methodName");

        //3.加载该类进内存
        Class cls =  Class.forName(className);
        //4.创建对象
        Object obj = cls.newInstance();
        //5. 获取方法对象
        Method method = cls.getMethod(methodName);
        method.invoke(obj);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值