反射的用法及概念

反射:框架设计的灵魂

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


* 获取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:获取方法名

Demo实战

测试pojo类

package com.xuan.reflexDemo.pojo;

import java.util.Date;

public class Student {
    public String name="李四";
    private int age = 18;
    public static Date time;

    public Student(){
        System.out.println("student 的无参构造方法");
    }

    public Student(int age){
        System.out.println("年龄:"+age);
    }

    public Student(String name){
        System.out.println("姓名:"+name);
    }


    public Student(String name,int age){
        System.out.println("名字为:"+name+",年龄为:"+age);
    }
    private Student(char age){
        System.out.println("年龄:"+age);
    }

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

    public void m2(String name) {
        System.out.println(name);
    }

    public String m3(String name,int age) {
        System.out.println(name+":"+age);
        return "aaa";
    }

    private void m4(Date d) {
        System.out.println(d);
    }

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

    public static void m6(String[] strs) {
        System.out.println(strs.length);
    }

    public static void main(String[] args) {
        System.out.println("main");
    }
}

Test测试类

TestFile
package com.xuan.reflexDemo.test;

import com.xuan.reflexDemo.pojo.Student;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

public class TestFiled {
/*    public String name="李四";
    private int age = 18;
    public static Date time;*/
    @Test
    public void test1() throws Exception{
        //public String name="李四"
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        //实例化
        Student instance = (Student)student.newInstance();
        Field name = student.getField("name");
        String s = (String) name.get(instance);
        System.out.println(s);

        name.set(instance,"wangwu");
        System.out.println(instance.name);

    }

    @Test
    public void test2() throws Exception{
        //private int age = 18;
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        //实例化
        Student instance = (Student)student.newInstance();
        Field age = student.getDeclaredField("age");
        age.setAccessible(true);
        int s =  (int) age.get(instance);
        System.out.println(s);

        age.set(instance,1888);
        int i = (int) age.get(instance);
        System.out.println(i);

    }

    @Test
    public void test3() throws Exception{
        //public static Date time
        //Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Class<Student> student = Student.class;
        Field time = student.getField("time");
        time.set(null, new Date());
        System.out.println(Student.time);

    }
}

TestMethod
package com.xuan.reflexDemo.test;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Date;

public class TestMethod {
    @Test
    public void test1() throws Exception{
        //空参方法======>必须加null不然会报错
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Method m1 = student.getMethod("m1",null);
        m1.invoke(student.newInstance(),null);
    }
    @Test
    public void test2() throws Exception{
        //获取单个参数方法并执行
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        //实例化字节码
        Object instance = student.newInstance();
        Method m2 = student.getMethod("m2", String.class);
        m2.invoke(instance,"安三");
    }
    @Test//public String m3(String name,int age)
    public void test3() throws Exception{
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        //实例化字节码
        Object instance = student.newInstance();
        Method m3 = student.getMethod("m3", String.class, int.class);
        m3.invoke(instance,"lisi",15);
    }


    @Test// private void m4(Date d)
    public void test4() throws Exception{
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        //实例化字节码
        Object instance = student.newInstance();
        Method m4 = student.getDeclaredMethod("m4", Date.class);
        m4.setAccessible(true);//私有需暴力反射
        m4.invoke(instance,new Date());
    }

    @Test//public static void m5() 静态方法不用实例化
    public void test5() throws Exception{
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Method m5 = student.getMethod("m5");
        m5.invoke(null);
    }

    @Test//public static void m6 静态方法不用实例化
    public void test6() throws Exception{
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Method m5 = student.getMethod("m6", String[].class);
        //m5.setAccessible(true);
        m5.invoke(null,(Object) new String[]{"a","b"});//把数组看做是一个Object对象
    }

    @Test//public static void main(String[] args)
    public void test7() throws Exception{
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Method m5 = student.getMethod("main", String[].class);
        m5.invoke(null,(Object) new String[]{"a","b","c"});
    }
}

TestConstructor
package com.xuan.reflexDemo.test;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestOne {
    /**
     * 构造方法测试 start
     */
    @Test
    public void test1() throws Exception{
        //空参构造方法
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Constructor c = student.getConstructor(null);
        c.newInstance(null);
    }
    @Test
    public void test2() throws Exception{
        //int参数的构造方法
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Constructor<?> constructor = student.getConstructor(int.class);
        constructor.newInstance(18);
    }
    @Test
    public void test3() throws Exception{
        //String类型的构造方法
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Constructor<?> constructor = student.getConstructor(String.class);
        constructor.newInstance("yiersan");
    }
    @Test
    public void test4() throws Exception{
        //多类型的构造方法
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Constructor<?> constructor = student.getConstructor(String.class,int.class);
        constructor.newInstance("zhangsan",15);
    }
    @Test
    public void test5() throws Exception{
        //私有的构造方法
        //在反射私有的构造函数时,用普通的clazz.getConstructor()会报错,因为它是私有的,
        // 所以提供了专门反射私有构造函数的方法 clazz.getDeclaredConstructor(int.class);//读取私有的构造函数,
        // 用这个方法读取完还需要设置一下暴力反射才可以
        Class<?> student = Class.forName("com.xuan.reflexDemo.pojo.Student");
        Constructor<?> constructor = student.getDeclaredConstructor(char.class);
        //暴力反射
        constructor.setAccessible(true);
        constructor.newInstance("1345".charAt(3));
    }
    /**
     * 构造方法测试 end
     */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值