zoukankan      html  css  js  c++  java
  • Java 反射

    1、在程序运行过程中,可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象。

    2、如果要获取一个类型的各种内容,首先要获取这个类的字节码对象,解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法。

    3、反射就是这种动态的获取信息以及动态的访问成员的方式,称为反射。

    4、获取类的字节码文件的三种方式

    public class Test{
    
        public static void main(String[] args) throws Exception {
            Student stu = new Student();
            //第一种方法:通过对象名.getClass()
            Class class1 = stu.getClass();
            //第二种方法:类名.class
            Class class2 = Student.class;
            //第三种方法:Class.forName(全类名)
            Class class3 = Class.forName("com.test1.Student");
            System.out.println(class1==class2);
            System.out.println(class1==class3);
        }
    
    }
    class Student{
        private String name;
        int age;
        private void run() {
            System.out.println("run run run");
        }
        public void setName(String name) {
            this.name = name;
        }
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Student() {}
    }
    获取.class文件的三种方式

    5、反射常用方法代码示例

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Test1 {
    
        public static void main(String[] args) throws Exception {
            Student stu = new Student();
            Class class1 = stu.getClass();
            //获取到的.class文件.getField(属性名)获取属性 
            //getFields获取所有属性到一个数组中
            Field f1 = class1.getDeclaredField("age");
            //可以设置属性
            System.out.println(stu.age);
            f1.set(stu, 15);
            System.out.println(stu.age);
            //上面的方式无法得到私有属性,需要暴力反射
            Field f2 = class1.getDeclaredField("name");
            //暴力反射也分getDeclaredField()和getDeclaredFields(),原理同getFiled和getFileds
            //想要设置私有属性必须使用setAccessible()将里面的参数设为true
            f2.setAccessible(true);
            System.out.println(stu);
            f2.set(stu, "qq");
            System.out.println(stu);
            
            //获取构造方法getConstructor(构造方法里的参数类型.class) 返回一个Constructor构造器
            //这个构造器可以使用newInstance() 创建一个object类型的对象
            Constructor c = class1.getConstructor(String.class,int.class);
            Object obj = c.newInstance("bb",10);
            Student stu2 = (Student)obj;
            System.out.println(stu2);
            //同理,构造器也有getConstructors和暴力反射
            
            //获取成员方法getMethod(方法名, 参数.class)
            Method m1 = class1.getMethod("setName",String.class);
            //方法的使用,方法.invoke(对象名,参数)
            m1.invoke(stu2, "hh");
            System.out.println(stu2);
            //同理,有getMethods和暴力反射getDeclaredMethod...
            Method m2 = class1.getDeclaredMethod("run",null);
            //同理需要设置权限
            m2.setAccessible(true);
            m2.invoke(stu);
        }
    
    }
    class Student{
        private String name;
        int age;
        private void run() {
            System.out.println(name+"run run run");
        }
        public void setName(String name) {
            this.name = name;
        }
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Student() {}
        @Override
        public String toString() {
            return name+"..."+age;
        }
    }
  • 相关阅读:
    任务二 发布作业信息(已完成)
    查看作业信息(任务一 已完成)
    项目冲刺任务之任务场景分析(四)
    项目冲刺之任务场景分析(三)
    解析XML文件的两种方式 SAX和DOM
    解析XML文件的两种方式 SAX和DOM
    iOS开发代码规范(通用)
    随机创建点击对象
    自定义加载等待框(MBProgressHUD)
    KVO、KVC
  • 原文地址:https://www.cnblogs.com/xfdhh/p/11260625.html
Copyright © 2011-2022 走看看