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

    反射的概念

    • Java反射机制是在运行状态时,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。

    • 通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。

    • 要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。

      image-20220106100421016

    获取class对象方式(3种方式)

    • Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

      多用于配制文件,将类名定义在配置文件中。读取文件,加载类。

    • 类名.class: 通过类名的属性class获取

      多用于参数的传递

    • 对象.getClass():getClass()方法在Object类中定义着。

      多用于对象的获取字节码的方式

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

    定义一个Person类,利用三种反射方式获取class对象

    //定义Person类
    public class Person {
        private String name;
        private int age;
    
        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;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    /*利用三种反射方式获取class对象
    	1、Class.forName("全类名")
    	2、类名.class
    	3、对象.getClass()
    */
    public class reflect {
        public static void main(String[] args) throws ClassNotFoundException {
            //Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
            Class cls1 = Class.forName("Person");
            System.out.println(cls1);//class Person
    
            //类名.class: 通过类名的属性class获取
            Class cls2 = Person.class;
            System.out.println(cls2);//class Person
    
            //对象.getClass():getClass()方法在Object类中定义着。
            Person person = new Person();
            Class cls3 = person.getClass();
            System.out.println(cls3);//class Person
    
            // == 比较3个对象
            System.out.println(cls1==cls2);//true
            System.out.println(cls2==cls3);//true
    
        }
    }
    
    

    反射对象的使用

    获取成员变量们

    Field [] getFields()		// 获取所有public修饰的成员变量 
    Field [] getField(String name)		//	获取指定名称的public修饰的成员变量
     
    Field [] getDeclaredFields() //获取所有的成员变量,不考虑修饰符
    Field [] getDeclaredFields(String name)  //获取指定的成员变量,不考虑修饰符
      
    
    //Demo 获取成员变量们,定义Person类,利用反射获取成员变量们
      public class Person {
        public int a;
        public String b;
        protected String c;
        private String name;
        private int age;
        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;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", a=" + a +
                    ", b='" + b + '\'' +
                    ", c='" + c + '\'' +
                    ", d='" + d + '\'' +
                    '}';
        }
    
        public void eat() {
            System.out.println("eat....");
    
        }
    
        public void eat(String food) {
            System.out.println("eat..." + food);
        }
    }
    
    
    
    //利用反射获取成员变量们
    import java.lang.reflect.Field;
    
    public class reflect {
        public static void main(String[] args) throws Exception {
            //0.获取Person的Class对象
            Class<Person> personClass = Person.class;
    
            //1.Field[] getFields()获取所有public修饰的成员变量
            Field[] fields = personClass.getFields();
            for (Field field : fields) {
                System.out.println(field);  //public int Person.a
                                            //public java.lang.String Person.b
            }
    
            System.out.println("=====================");
            //2.Field getField(String name)
            Field b = personClass.getField("b");
            //获取成员变量a的值
            Person p = new Person();
            Object value = b.get(p);
            System.out.println(value); // null
            //设置a的值
            b.set(p,"张三");
            System.out.println(p);//Person{name='null', age=0, a=0, b='张三', c='null', d='null'}
    
            System.out.println("================");
    
            //Field [] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
            Field[] declaredFields = personClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField);
            }
            /*
            private java.lang.String Person.name
            private int Person.age
            public int Person.a
            public java.lang.String Person.b
            protected java.lang.String Person.c
            private java.lang.String Person.d
             */
    
    
            //Field getDeclaredField(String name)
            Field d = personClass.getDeclaredField("d");
            //忽略访问权限修饰符的安全检测
            d.setAccessible(true); //暴力反射
            Object value2 = d.get(p);
            System.out.println(value2); //null
            //Field [] getDeclaredFields(String name)
        }
    }
    

    获取构造方法们

    Constructor<?>[] getConstructors()
    Constructor<T> getConstructor(类<?>... parameterTypes)
      
    Constructor<?>[] getDeclaredConstructors()
    Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    public class reflect2 {
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //0.获取Person的Class对象
            Class<Person> personClass = Person.class;
            //Constructor<T> getConstructor(类<?>... parameterTypes)
            Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
            //创建对象
            Person p = constructor.newInstance("张三", 28);
            System.out.println(p);//Person{name='张三', age=28, a=0, b='null', c='null', d='null'}
    
    
    
            Constructor<Person> constructor2 = personClass.getConstructor();
            Person p2 = constructor2.newInstance();
            System.out.println(p2);//Person{name='null', age=0, a=0, b='null', c='null', d='null'}
    
            Person p3 = personClass.newInstance();
            System.out.println(p3);
        }
    }
    
    

    获取成员方法们

    Method[] getMethods()
    Method getMethod(String name,类<?>... parameterTypes)
      
    Method[] getDeclaredMethods()
    Method getDeclaredMethod(String name,类<?>... parameterTypes)
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class reflect3 {
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //0.获取Person的Class对象
            Class<Person> personClass = Person.class;
    
            //获取指定名称的方法
            Method eat_method = personClass.getMethod("eat");
    
            //执行方法
            Person p = new Person();
            eat_method.invoke(p);//eat....
    
    
            Method eat_method2 = personClass.getMethod("eat",String.class);
            eat_method2.invoke(p,"饭");//eat...饭
    
            Method[] methods = personClass.getMethods();
            for (Method method : methods) {
                //System.out.println(method);
                String name = method.getName();
                System.out.println(name);
            }
    
            //获取类名
            String className = personClass.getName();
            System.out.println(className);
        }
    }
    
    

    获取类名

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

    我们欠生活一个努力!
  • 相关阅读:
    Python面向对象:继承和多态
    Python面向对象:类、实例与访问限制
    Python正则表达式匹配猫眼电影HTML信息
    Git:从github上克隆、修改和更新项目
    Python:闭包
    JPA-映射-(@ManyToMany)双向多对多
    rownum详解
    java之yield(),sleep(),wait()区别详解
    springmvc<一>一种资源返回多种形式【ContentNegotiatingViewResolver】
    @RequestParam,@PathVariable,@ResponseBody,@RequestBody,@ModelAttribute学习
  • 原文地址:https://www.cnblogs.com/lalalaxiaoyuren/p/15769912.html
Copyright © 2011-2022 走看看