Java反射第二篇

Artio 于 2022-04-24 发布

Java反射

一、定义

Java反射机制是在程序运行状态下,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用这个对象的任意方法和属性;这样动态或者以及动态调用的功能就叫反射。

二、基本运用

  1. 获取类对象
    • forName()方法
      • 如果要使用Class类中的方法获取类对象,就需要使用forName方法,只需要类名称即可。

      • 这种方法并不陌生,在配置JDBC的时候,我们通常使用这种方法。

      • public class forname {
            public static void main(String[] args) throws ClassNotFoundException{
                Class name = Class.forName("java.lang.Runtime");
                System.out.println(name);
            }
        }
        
    • 直接获取

      • 任何数据类型都具备静态的属性,因此可以使用.class 直接获取其对应的Class对象,但要明确用到类中的静态成员。

      • public class direct {
            public static void main(String[] args) throws ClassNotFoundException{
                Class name = Runtime.class;
                System.out.println(name);
            }
        }
        
    • getClass()方法

      • 我们可以通过Object类中的getClass方法来获取字节码对象,不过这种方法较为繁琐,必须先要明确具体的类,然后创建对象a,然后a.getClass()获取。

      • public class getClass {
            public static void main(String[] args) throws ClassNotFoundException{
                Runtime rt = Runtime.getRuntime();
                Class name = rt.getClass();
                System.out.println(name);
            }
        }
        
    • getSystemClassLoader().loadClass方法
      • 该方法与forName方法类似,只要有类名称即可,但是与forName方法有些区别:

      • forName的静态方法JVM会装载类,并且执行static()中的代码;

      • getSystemClassLoader().loadClass()不会执行static()中的代码;

      • 比如前边提到的JDBC就是利用forName方法,使JVM查找并加载制定的类到内存,此时将”com.mysql.jdbc.Driver”当作参数传入,就是告知JVM去”com.mysql.jdbc”路径下查找Driver类,并将其加载到内存中。

      • public class getSystemClassLoader_loadClass {
            public static void main(String[] args) throws ClassNotFoundException{
                Class<?> name = ClassLoader.getSystemClassLoader().loadClass("java.lang.Runtime");
                System.out.println(name);
            }
        }
        
  2. 获取类方法
    • getDeclaredMethods方法

      • 该方法返回类或接口声明的所有方法,包括public、protected、private和默认方法,但不包括继承的方法。

      • import java.lang.reflect.Method;
               
        public class getDeclaredMethods {
            public static void main(String[] args) throws ClassNotFoundException{
                Class<?> name = Class.forName("java.lang.Runtime");
                Method[] declaredMethods = name.getDeclaredMethods();
                System.out.println("通过getDeclaredMethods方式获取方法:");
                for (Method m:declaredMethods)
                    System.out.println(m);
            }
        }
        
    • getMethods方法

      • 该方法返回某个类的所有public方法,包括其继承类的public方法。

      • import java.lang.reflect.Method;
               
        public class getMethods {
            public static void main(String[] args) throws ClassNotFoundException{
                Runtime rt = Runtime.getRuntime();
                Class<?> name = rt.getClass();
                Method[] methods = name.getMethods();
                System.out.println("通过getMethods方式获取的方法:");
                for (Method m:methods)
                    System.out.println(m);
            }
        }
        
    • getMethod方法

      • 该方法只能返回一个特定的方法,如Runtime类中的exec方法,该方法的第一个参数为方法名称,后边的参数为方法的参数对应Class的对象。

      • import java.lang.reflect.Method;
               
        public class getMethod {
            public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException{
                Runtime rt = Runtime.getRuntime();
                Class<?> name = rt.getClass();
                Method method = name.getMethod("exec", String.class);
                System.out.println("通过getMethod方式获取的方法:");
                System.out.println(method);
            }
        }
        
    • getDeclaredMethod方法

      • 该方法与getMethod方法类似,也只能返回一个特定的方法,该方法的第一个参数为方法名,第二个是方法参数。

      • import java.lang.reflect.Method;
               
        public class getDeclaredMethod {
            public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException{
                Runtime rt = Runtime.getRuntime();
                Class<?> name = rt.getClass();
                Method method = name.getDeclaredMethod("exec", String.class);
                System.out.println("通过getDeclaredMethod方式获取的方法:");
                System.out.println(method);
            }
        }
        
  3. 获取类成员变量
    • getDeclaredFields方法

      • 该方法可以获得类的成员变量数组,包括public、private和proteced,但是不包括父类的申明字段。

      • import java.lang.reflect.Field;
               
        public class getDeclaredFields {
            public static void main(String[] args) throws ClassNotFoundException{
                Student student = new Student();
                Class<?> name = student.getClass();
                Field[] getDeclaredFields = name.getDeclaredFields();
                System.out.println("通过getDeclaredFields方式获取的方法:");
                for (Field f:getDeclaredFields)
                    System.out.println(f);
            }
        }
        
    • getFields方法

      • 该方法能够获得某个类的所有public字段,包括父类中的字段。

      • import java.lang.reflect.Field;
               
        public class getFields {
            public static void main(String[] args) throws ClassNotFoundException{
                Student student = new Student();
                Class<?> name = student.getClass();
                Field[] getFields = name.getFields();
                System.out.println("通过getFields方式获取的字段:");
                for (Field f:getFields)
                    System.out.println(f);
            }
        }
        
    • getDeclaredField方法

      • 该方法与getDeclaredFields的区别是只能获取类的单个成员变量

      • import java.lang.reflect.Field;
               
        public class getDeclaredField {
            public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException{
                Student student = new Student();
                Class<?> name = student.getClass();
                Field getDeclaredField = name.getDeclaredField("name");
                System.out.println("通过getDeclaredField方式获取方法:");
                System.out.println(getDeclaredField);
            }
        }
        
    • getField方法

      • 与getFields方法类似,该方法能够获得某个类特定的public字段,包括父类中的字段

      • import java.lang.reflect.Field;
               
        public class getField {
            public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException{
                Student student = new Student();
                Class<?> name = student.getClass();
                Field getField = name.getField("content");
                System.out.println("通过getField方式获取方法:");
                System.out.println(getField);
            }
        }