• Java之反射


    目录

    1.什么是反射机制

    2.反射机制有什么用

    3.Class类对象的三种实例化模式

    1.getClass()方法:

    2.类.class

    3.使用Class类提供的方法

    4. 通过反射实例化对象

    5.反射主要使用的种类

    5.1Class类方法:

    5.2Field类方法

    5.3:Method方法


    1.什么是反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的法的功能称为java语言的反射机制。

    2.反射机制有什么用

    通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件。)

    通过反射机制可以操作代码片段。(class文件。)

    3.Class类对象的三种实例化模式

    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

    Class类对象的三种实例化模式:

    以下分别举例实现:

    1.getClass()方法:

    public final native Class<>getClass()

    范例:调用getClass()方法

    import  java.util.Date;
    public class test {
        public static void main(String[] args) {
            Date date=new Date();
            System.out.println(date.getClass());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果:找到对应的类

    2.类.class

    范例:通过类名找对应的class 文件

    import java.util.Date;
    
    public class test {
        public static void main(String[] args) throws  Exception{
            System.out.println(Date.class);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:

    3.使用Class类提供的方法:public static Class forName(String className) throws ClassNotFoundException

    范例:使用Class.forName()方法

    package 反射;
    import  java.lang.Class;
    public class test {
        public static void main(String[] args) throws  Exception{
            Class date =Class.forName("java.util.Date");
            System.out.println(date);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:

    4. 通过反射实例化对象

    以上事例中可以看出除了getClass()方法会实例化对象之外,其他的俩种不会产生实例化对象,所以取得Class类对象的一个最直接的好处就是通过**反射实例化对象****,**该方法为:

    对象.newInstance()

    newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以
    否则会抛出java.lang.InstantiationException异常。

    范例:

    package 反射;
    import  java.lang.Class;
    import java.util.Date;
    
    public class test {
        public static void main(String[] args) throws Exception{
            //通过反射机制,获取Class,通过Class来实例化对象
            Class  cl=Class.forName("java.util.Date");
            //newInstance() 这个方法会调用Date这个类的无参数构造方法,完成对象的创建。
            // 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
            Object object=cl.newInstance();
            System.out.println(object);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5.反射主要使用的种类

    5.1Class类方法:

    举例常见的几种方法:

    1.获取类名

    import 新特性.泛型.泛型接口.test;
    public class demo {
        public static void main(String[] args) throws  Exception {
            Class cl=test.class;
            System.out.println(cl.getName());
            System.out.println(cl.getSimpleName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:

    2.获取类中的所有方法(重要)

    import java.lang.reflect.Method;
    import 新特性.泛型.泛型类方法.test;
    
    public class getMethod {
        public static void main(String[] args) throws Exception {
            //通过反射机制,获取Class,通过Class来实例化对象
            Class cl = test.class;
            //通过getMethods方法获取所有public修饰的普通方法
            Method[] methods = cl.getMethods();
            for (Method i : methods) {
                System.out.println(i.getName());
            }
            System.out.println();
            //通过getDeclaredMethods返回类中所有的实例方法
            Method[] methods1 = cl.getDeclaredMethods();
            for (Method i : methods1) {
                System.out.println(i.getName());
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5.2Field类方法

    范例:

    import java.lang.reflect.Field;
    
    class Person{
            public String name;
            public   int age;
    }
    
    class Student extends Person
    {
         public String school;
    }
    public class getField {
            public static void main(String[] args)  throws  Exception{
                    Class cl= Student.class;1
    
                    Field[] fields=cl.getFields();
                    //返回public修饰的所有属性
                    for (Field field:fields)
                    {
                            System.out.println(field.getName());
                    }
                    System.out.println();
                    //返回本类中的所有属性
                    Field[] fie=cl.getDeclaredFields();
                    for (Field field:fie)
                    {
                            System.out.println(field.getName());
                    }
                    //通过反射操作属性-----set/get方法
                    Object obj=cl.newInstance();
                    Field getFid=cl.getDeclaredField("school");
                    getFid.set(obj,"华润希望小学");
                    System.out.println(getFid.get(obj));
    
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    结果:

    5.3:Method方法

    重点getMethod()方法和invoke方法

    范例:在有了反射机制处理之后,即使没有明确的Person类型对象(依然需要实例化对象,Object对象描述,所有 的普通方法必须在有实例化对象之后才可以进行调用)。就可以通过反射调用。通过反射去调用setter,getter方法

    Method getMethod(String name,Class…parameterTypes)

    name: method的名称

    parameterTypes:method的参数类型的列表(参数顺序需按声明method时的参数列表排列)

    返回:符合method名称和参数的method对象

    抛出错误:NoSuchMethodException(没有找到所要查询的Method对象或Method名称为“”或“”) NullPointerException (所要查询的Method对象的名称为null) SecurityException(调用的类或其父类没有调用权限)

    invoke方法:

    作用:调用包装在当前Method对象中的方法。

    原型:Object invoke(Object obj,Object…args) 参数解释:obj:实例化后的对象 args:用于方法调用的参数

    返回:根据obj和args调用的方法的返回值

    抛出错误:IllegalAccessException(Method对象强制Java语言执行控制或无权访问obj对象) IllegalArgumentException(方法是实例化方法,而指定需要调用的对象并不是实例化后的类或接口)

    import java.lang.reflect.Method;
    class Person
    {
        private  String name;
        private  int age;
        private  String sex;
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    
        public String getSex() {
            return sex;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    public class getMethod {
        public static void main(String[] args) throws Exception {
            //通过类名.class获取class对象
            Class cl=Person.class;
            //实例划对象
            Object o=cl.newInstance();
            //通过getMethon方法取得setName这个方法的实例化对象,方法名称与参数类型
            Method setMethod=cl.getMethod("setName", String.class);
            //通过invoke调用方法
            setMethod.invoke(o,"wangyang");
            Method  getMethod=cl.getMethod("getName");
            Object result=getMethod.invoke(o);
            System.out.println(result);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    此类操作的好处是:不再局限于某一具体类型的对象,而是可以通过Object类型进行所有类的方法调用。这个操作 必须掌握.

    可参考Java反射(超详细!)_一只小菜鸡-CSDN博客_java反射

  • 相关阅读:
    计算机网络 | 07.[HTTP篇]HTTP/1.0、HTTP/1.1和HTTP/2.0
    Java String、StringBuffer 和 StringBuilder 的区别和理解
    独角数卡安装前后常见问题汇总
    Centos7-Failed to start LSB: Bring up/down networking
    老杨说运维|今年这个会议非比寻常
    在 Linux 环境下的简单调试技巧
    ChatGPT - 在ChatGPT中设置通用提示模板
    基于nodejs+vue+elementui酒店民宿客房预订管理系统
    Java新手小白入门篇 Java面向对象(六)
    处理两路差分信号的中心位置的算法实现(python)
  • 原文地址:https://blog.csdn.net/m0_67391270/article/details/126020239