zoukankan      html  css  js  c++  java
  • java学习----反射

     目录

     1.什么是反射

      2.反射的运用

      3.总结

     

    一、什么是反射

      反射:反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力   ----by  维基百科

      java中的反射也是如此,利用反射的原理我们可以在程序运行时候的能够动态的创建对象,并且调用对象的方法和属性

      它的作用是:1.在运行时判断任意一个对象类型

            2.在运行时候能够构造任意一个对象

            3.在运行时候判断一个类的属性和方法

      反射在实际开发中的运用主要是在编写第三方jar包中比较多。我们可以运用反射对程序进行反编译。

    二、反射的运用

      上面涉及到反射是在java程序运行时才出现的。我们知道java程序运行的机制是先编译再运行。

      编译后我们会得到一个以.class结尾的字节码文件。我们要运行一个java程序,只需要这个文件+JVM虚拟机即可

      那么就简单了解一下jvm的类加载机制(类的生命周期)吧

      

      在java中反射的核心类是Class类

      接下来就看看反射的核心类Class吧。

       创建反射(Class)对象有三中方法

      1.Class.forName(全路径名);

        2.类型  对象名 = new 类型();

       对象名.getClass();

      3.类名.class;

     ps:该类型不管创建多少个对象,通过对象

    获取的Class对象,都是同一个。

    下面看一个反射的实例吧:

      

    package com.demo.forname;
    
    public class Student {
        private String name;
        private Integer id;
        public int age;
        private Student(int id){
            this.id=id;
        }
        public Student(){
            System.out.println("执行了无参的构造方法");
        }
        public Student(String name, Integer id, int age) {
            super();
            this.name = name;
            this.id = id;
            this.age = age;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", id=" + id + ", age=" + age + "]";
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
    }
    需要进行反射操作的类
    package com.demo.forname;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class ReflectNewObject {
        public static void main(String[] args) throws Exception {
            //获取反射对象
            Class<Student> obj = (Class<Student>) Class.forName("com.demo.forname.Student");
            //调用无参构造方法
            Student stu1 = obj.newInstance();
            //选择需要调用的构造方法
            Constructor constructor = obj.getConstructor(String.class,Integer.class,Integer.TYPE);
            //有Constructor对象调用构造方法
            Student stu2 = (Student)constructor.newInstance("张三",23,23);
            System.out.println(stu2);
            //------------------------------------------------------------------------------------
            //获取所有的属性(只含公开属性,包含父类的属性)
            Field[] f = obj.getFields();
            for (Field field : f) {
                System.out.println(field);
            }
            System.out.println("-----------------------------");
            //获取指定字段的属性(只包含公开属性,包含父类的属性)
            Field f3 = obj.getField("name");
            System.out.println(f3);
            System.out.println("-----------------------------");
            //获取当前类中指定的属性(只包含本类)
            Field f4 = obj.getDeclaredField("name");
            System.out.println(f4);
            System.out.println("----------------------------");
            //获取本类所有的属性
            Field[] f2 = obj.getDeclaredFields();
            for (Field field : f2) {
                System.out.println(field);
            }
            System.out.println("****************************");
            //-------------------------------------------------------------------------------------
            //获取所有的方法(只包含公开的,包含父类(别忘了Object类中的方法))
            Method[] m1 = obj.getMethods();
            for (Method method : m1) {
                System.out.println(method);
            }
            System.out.println("****************************");
            //获取本类中所有的方法(不包含父类)
            Method[] m2 = obj.getDeclaredMethods();
            for (Method method : m2) {
                System.out.println(method);
            }
            System.out.println("****************************");
            //获取指定方法(需要公开的方法,不包含父类)后面的参数类型写该方法的参数的Class对象,如果没有就写null或不写
            Method m3 = obj.getMethod("toString");
            System.out.println(m3);
            //获取当前类中的指定方法(所有方法)
            System.out.println("****************************");
            Method m4 = obj.getDeclaredMethod("tec",int.class,String.class);
            //由于这里的m4方法是私有的这里利用反射我们可以让方法变成公开的来执行
            m4.setAccessible(true);
            System.out.println(m4);
            //调用方法(,这里方法没有参数则写null,但是第一个参数必须是这个方法的对象)
            m4.invoke(stu1,1,"789");
        }
    }
    利用反射运行代码

    3、总结

      java反射机制由于是在编译后且是在JVM运行时进行的操作,所以我们可以运用反射完成平常做不到的事。比如:集合里放不同的类型、调用私有的方法等等。

    这里java的优势就体现出来了----增加了代码的灵活性但是由于java反射的这些代码还要重新进行编译,所以利用反射写出来的代码运行效率是很低的,并且利用反射

    写代码是非常繁琐的。所以善用java反射才能写出更好的代码。

  • 相关阅读:
    Wolfram常用计算
    soapUI接口关联教程
    时间序列预测线上充值数据
    基于MySQL分析线上充值留存率
    更改用户资料需要完善脚本
    MySQL建立RFM模型
    Scrcpy使用入门
    虾皮Shopee社招面经分享(大数据开发方向),附内推方式
    MySQL Binlog 解析工具 Maxwell 详解
    MySQL Binlog 介绍
  • 原文地址:https://www.cnblogs.com/bananafish/p/9744405.html
Copyright © 2011-2022 走看看