反射的应用

反射的应用,第1张

反射的应用 1. 反射需要用到的API 1.1 获取字节码对象

Class.forName(“类的全路径”); 注意:传入的是类的全路径名,包含包名.类名,而且会抛出异常

类名.class 注意:这个写法需要自己手动接一下获取到的字节码对象,不能用快捷方式的

对象.getClass(); 注意:经常与匿名对象一起使用

1.2 常用方法

获取包名 类名

clazz.getPackage().getName()//包名 clazz.getSimpleName()//类名 clazz.getName()//完整类名

获取成员变量定义信息

getFields()//获取所有公开的成员变量,包括继承变量 getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量 getField(变量名) getDeclaredField(变量名)

获取构造方法定义信息

getConstructor(参数类型列表)//获取公开的构造方法 getConstructors()//获取所有的公开的构造方法 getDeclaredConstructors()//获取所有的构造方法,包括私有 getDeclaredConstructor(int.class,String.class)

获取方法定义信息

getMethods()//获取所有可见的方法,包括继承的方法 getMethod(方法名,参数类型列表) getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法 getDeclaredMethod(方法名,int.class,String.class)

反射新建实例

clazz.newInstance();//执行无参构造创建对象 clazz.getConstructor(int.class,String.class)//要先获取构造方法 clazz.newInstance(666,”海绵宝宝”);//再执行含参构造创建对象

反射调用成员变量

clazz.getDeclaredField(变量名);//获取变量 field.setAccessible(true);//使私有成员允许访问 field.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null field.get(实例);//访问指定实例变量的值,静态变量,第一参数给null

反射调用成员方法

Method m = Clazz.getDeclaredMethod(方法名,参数类型列表); m.setAccessible(true);//使私有方法允许被调用 m.invoke(实例,参数数据);//让指定实例来执行该方法

package cn.tedu.reflection;

public class Student{
    //1.定义成员变量
    public String name;
   public int age;
    //2.提供本类的无参与全参构造
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Student() {
    }
    public void play(){
        System.out.println("今天大结局,放学后写10000行代码");
    }
    public void eat(int n){
        System.out.println("在忙我也要吃"+n+"碗大米饭");
    }
//4.重写toString(),为了查看对象的类型 属性 属性值
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}


 

package cn.tedu.reflection;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;


public class TestReflect {
    
    @Test
    public void getClazz() throws ClassNotFoundException {
        //练习获取字节码对象的3种方式
        Class Clazz1 = Class.forName("cn.tedu.reflection.Student");
        Class Clazz2 = Student.class;
        Class Clazz3 = new Student().getClass();
        System.out.println(Clazz1.getClass().getName());//java.lang.Class
        System.out.println(Clazz1);//class cn.tedu.reflection.Student
        System.out.println(Clazz1.getName());//cn.tedu.reflection.Student
        System.out.println(Clazz1.getSimpleName());//Student
        System.out.println(Clazz1.getPackage());//package cn.tedu.reflection
        System.out.println(Clazz1.getPackage().getName());//cn.tedu.reflection
    }

    
    @Test
    public void getFie() throws ClassNotFoundException {
        //1.获取字节码对象
        Class clazz = Class.forName("cn.tedu.reflection.Student");
        //2.通过字节码对象,获取目标类中所有的成员变量
        Field[] fs = clazz.getFields();
        //3.遍历数组,获取每个成员变量的具体信息
        
        for (Field f :
                fs) {
            System.out.println(f.getName());//name   age
            System.out.println(f.getType());//class java.lang.String    int
//            name
//            class java.lang.String
//                    age
//            int
        }
    }

    
    @Test
    public void getSu() {
        //1.创建Student类的3个对象
        Student s1 = new Student("张三", 3);
        Student s2 = new Student("李四", 4);
        Student s3 = new Student("王五", 5);
        //2.将创建好的3个对象放入Student类型的数组中
        Student[] s = {s1, s2, s3};
        //3.通过遍历,在每轮循环获取每一个学生对象
        for (Student hh :
                s) {
            System.out.println(hh.name);
            hh.eat(8);
            hh.play();
            

        }
    }

    
    @Test
    public void getFunction() {
        //1.获取字节码对象
        Class clazz = Student.class;
//通过字节码对象获取目标类对应的所有成员方法们
        Method[] ms = clazz.getMethods();
        //3.通过高效for循环遍历数组,每轮循环拿到一个方法对象
        for (Method s :
                ms) {
//            System.out.println(s+" ");
//            public java.lang.String cn.tedu.reflection.Student.toString()
//            public void cn.tedu.reflection.Student.play()
//            public void cn.tedu.reflection.Student.eat(int)
//            public final void java.lang.Object.wait() throws java.lang.InterruptedException
//            public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//            public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//            public boolean java.lang.Object.equals(java.lang.Object)
//            public native int java.lang.Object.hashCode()
//            public final native java.lang.Class java.lang.Object.getClass()
//            public final native void java.lang.Object.notify()
//            public final native void java.lang.Object.notifyAll()
//            System.out.println("方法名字"+s.getName());
//            方法名字toString
//                    方法名字play
//            方法名字eat
//                    方法名字wait
//            方法名字wait
//                    方法名字wait
//            方法名字equals
//                    方法名字hashCode
//            方法名字getClass
//                    方法名字notify
//            方法名字notifyAll
            //通过本轮循环获取到方法对象,进一步获取这个方法的参数类型
            Class[] pt = s.getParameterTypes();
//            System.out.println(pt);
//            [Ljava.lang.Class;@5e8c92f4
//                    [Ljava.lang.Class;@61e4705b
//                    [Ljava.lang.Class;@50134894
//                    [Ljava.lang.Class;@2957fcb0
//                    [Ljava.lang.Class;@1376c05c
//                    [Ljava.lang.Class;@51521cc1
//                    [Ljava.lang.Class;@1b4fb997
//                    [Ljava.lang.Class;@deb6432
//[Ljava.lang.Class;@28ba21f3
//                    [Ljava.lang.Class;@694f9431
//                    [Ljava.lang.Class;@f2a0b8e
            System.out.println(Arrays.toString(pt));
//            []
//[]
//[int]
//[]
//[long, int]
//[long]
//[class java.lang.Object]
//[]
//[]
//[]
//[]
        }
    }
    
    @Test
    public void getCons(){
        //1.获取字节码对象
        Class clazz= new Student().getClass();
        //2.通过字节码对象 获取目标类中的构造方法们
        Constructor[] cs = clazz.getConstructors();
        //3.通过高效for循环遍历,拿到每一个构造函数对象
        for (Constructor c:
             cs) {
           System.out.println(c.getName());//cn.tedu.reflection.Student      cn.tedu.reflection.Student
            Class[] pt = c.getParameterTypes();
            for (Class p:
                pt ) {
               System.out.println(Arrays.toString(pt));//[class java.lang.String, int]  [class java.lang.String, int]
            }


        }
    }

    
    @Test
    public void getObject() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.获取字节码对象
        Class clazz = Student.class;
        //2.利用反射创建目标业务类对象
        
        Object o = clazz.newInstance();
        System.out.println(o);//Student{name='null', age=0}
        
        //3.获取指定的构造函数对象,注意要获取构造方法,需要指定参数类型,而且是字节码对象
        Constructor c = clazz.getConstructor(String.class ,int.class);
        //4.利用获取到的全参构造对象,创建目标类Student的对象
        //构造方法 传参数
        Object o2 = c.newInstance("赵六", 18);
        //5.打印创建好的学生类对象,可以看到属性也被赋值了
        System.out.println(o2);
    }
}
 练习2
package cn.tedu.reflection;

public class Person {
    //1.提供私有属性
    private String name;
    private int age;
    private String addr;
    //2.提供私有方法
    private void save(int n,String s){
        System.out.println("save方法"+n+s);
    }
    private  void update(){
        System.out.println("update方法");
    }
}
package cn.tedu.reflection;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class Testreflect2 {
    
    @Test
    public void getFile2() throws Exception {
        //1.获取字节码对象
        Class clazz = Person.class;
        //2.获取指定它的私有属性,注意需要传入属性名,确认要获取哪个私有属性
        Field field = clazz.getDeclaredField("name");
        //3.根据获取到的属性值,查看属性的类型
        System.out.println(field);//private java.lang.String cn.tedu.reflection.Person.name
        System.out.println(field.getType().getName());//java.lang.String
        System.out.println(field.getType());//class java.lang.String
        //4.设置属性的值
        //4.1需要指定到底给哪个对象的name属性设置一个什么值
        Object obj = clazz.newInstance();//触发无参构造创建对象
        //4.2暴力反射,需要设置私有资源可见权限
        field.setAccessible(true);
        //fileld就是我们刚刚获取的name值
        //set(m,n)---m是给哪个对象的name属性设置值,n是设置的具体值
        field.set(obj, "赵六");
        //4.4打印查看刚刚的属性值是否设置成功
        //filed.get(m),m代表的就是给哪个对象的这个name属性的值
        System.out.println(field.get(obj));//赵六
    }

    
    @Test
    public void getFile3() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class clazz = Person.class;//获取字节码对象
        Field addr = clazz.getDeclaredField("addr");//获取addr属性对象
        addr.setAccessible(true);//设置属性私有可见的权限
        Object o = clazz.newInstance();//准备好要给哪个对象设置属性值
        addr.set(o, "北京");//给p3对象的field(addr属性)设置值为“北京”
        System.out.println(addr.get(o));//北京,查看属性值是否设置成功
    }

    
    @Test
    public void getFunction2() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //1.获取字节码对象
        Class clazz = new Person().getClass();
        //2.通过字节码对象获取私有方法
        
        Method save = clazz.getDeclaredMethod("save", int.class, String.class);
        //通过反射创建目标类Person对应的对象
        Person p1 = clazz.newInstance();
        save.setAccessible(true);
        
        save.invoke(p1, 18, "秦仙女");//save方法18秦仙女

    }

    @Test
    public void getFunction3() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class clazz = Person.class;
        Method update = clazz.getDeclaredMethod("update");
        update.setAccessible(true);
        Object o = clazz.newInstance();
        update.invoke(o);//update方法
    }
}

 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5721806.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存