• Java反射


    概念既定

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。简单的来说反射是:指程序可以访问、检测和修改它本身状态或行为的一种能力

    用途用法

    在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法


     一切反射相关的代码都从获得类(java.lang.Class)对象开始,下面是获取类对象三种方法

    1 Class.forName(完整类名)
    2 类名.class
    3 类实例对象.getClass()

    在获取类对象是如果报ClassNotFoundException异常,则是类名错误,或者没有导包。

    同一个类的、类对象只会创建一个

    先创建一个Student类,如下:

    public class Student {
        private String sid;
    
        private String sname;
    
        public Integer age;
        
        static{
            System.out.println("加载进jvm中!");
        }
    
        public Student() {
            super();
            System.out.println("调用无参构造方法创建了一个学生对象");
        }
    
        public Student(String sid) {
            super();
            this.sid = sid;
            System.out.println("调用带一个参数的构造方法创建了一个学生对象");
        }
    
        public Student(String sid, String sname) {
            super();
            this.sid = sid;
            this.sname = sname;
            System.out.println("调用带二个参数的构造方法创建了一个学生对象");
        }
    
        @SuppressWarnings("unused")
        private Student(Integer age) {
            System.out.println("调用Student类私有的构造方法创建一个学生对象");
            this.age = age;
        }
    
        public String getSid() {
            return sid;
        }
    
        public void setSid(String sid) {
            this.sid = sid;
        }
    
        public String getSname() {
            return sname;
        }
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        public void hello() {
            System.out.println("你好!我是" + this.sname);
        }
    
        public void hello(String name) {
            System.out.println(name + "你好!我是" + this.sname);
        }
    
        @SuppressWarnings("unused")
        private Integer add(Integer a, Integer b) {
            return new Integer(a.intValue() + b.intValue());
        }
    
        @Override
        public String toString() {
            return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
        }
    }

    获取类对象

    public class Dome1 {
        public static void main(String[] args) throws ClassNotFoundException {
            // 1,类名.Class.forName
            Class<?> clz = Class.forName("com.zking.reflect.Student");
            // 2,类名.class
            Class<?> clz1 = Student.class;
            // 3,类实例对象.getClass()
            Student stu = new Student();
            Class<?> clz2 = stu.getClass();
            System.out.println(clz);
            System.out.println(clz1);
            System.out.println(clz2);
    
        }

    反射三大作用

    1 实例化对象(能够实例化未知的对象 能够通过私有构造器创建实例)

     

    c实例.newInstance()

    getConstructor只能寻找到public的修饰的构造器,getDeclaredConstructor可以寻找到任何修饰符修饰的构造器

    如果报java.lang.NoSuchMethodException的错,表示构造器方法是private修饰的,要使用getDeclaredConstructor方法

    如果使用getDeclaredConstructor报错:

    java.lang.IllegalAccessException: Class com.zking.reflect.Demo2 can not access a member of class com.zking.reflect.Student with modifiers "private"

    是因为,private方法无法访问,需设置;

    .setAccessible(true);

    注:一定要提供一个无参构造器

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    public class Demo2 {
        public static void main(String[] args) throws Exception {
    
            Class clz = Student.class;
    //        反射调用无参构造方法创建了一个学生对象
            Student stu = (Student) clz.newInstance();
    //        要拿到构造类
            Constructor con=clz.getConstructor(String.class);
            
    //        通过构造器实例化对象
            Student stu1=(Student)con.newInstance("s001");
            
    //        调用带二个参数的构造方法创建了一个学生对象
            Constructor con2=clz.getConstructor(String.class,String.class);
    //        通过构造器实例化对象
            Student stu2=(Student)con2.newInstance("s001","zs");
            
    //        调用Student类共有的构造方法创建一个学生对象
            Constructor con3=clz.getConstructor(String.class);
            Student stu3=(Student)con3.newInstance("s001");
            
            
    //        调用Student类私有的构造方法创建一个学生对象
            Constructor con4=clz.getDeclaredConstructor(Integer.class);
            con4.setAccessible(true);
            //通过构造器实例化对象
            Student stu4=(Student)con4.newInstance(12);
            
            
        }
    }

    2 动态调用方法

    public class Demo3 {
    
        public static void main(String[] args) throws Exception {
            Student stu=new Student();
            stu.hello();
            Class clz=stu.getClass();
            Method m= clz.getDeclaredMethod("hello");
            m.invoke(stu);
            
            
            Method m1= clz.getDeclaredMethod("add",Integer.class,Integer.class);
            m1.setAccessible(true);
    //        invoke:如果反射动态调用的方法是被void所修饰,那么返回的就是null
    //        如果反射动态调用的方法不被void所修饰, 那么返回的就是被调用的方法的返回值
            Object invoke=m1.invoke(stu,20,5);
            System.out.println(invoke);
        }
    }

    3 读写属性

    public class Demo4 {
    
        public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
            Student stu=new Student("s001","ls");
            stu.age=22;
            Class clz=stu.getClass();
            Field[] fields=clz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                System.out.println(field.getName()+" : "+field.get(stu));
            }
        }
    }

     

  • 相关阅读:
    [Swift实际操作]七、常见概念-(5)使用NSString对字符串进行各种操作
    [Swift]LeetCode326. 3的幂 | Power of Three
    [Swift]LeetCode303. 区域和检索
    [Swift]LeetCode292. Nim游戏 | Nim Game
    [Swift]LeetCode290. 单词模式 | Word Pattern
    SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
    一个Web报表项目的性能分析和优化实践(七):性能监测工具JavaMelody
    一个Web报表项目的性能分析和优化实践(七):性能监测工具JavaMelody
    百度Echarts-免费的商业产品图表库
    百度Echarts-免费的商业产品图表库
  • 原文地址:https://www.cnblogs.com/huxiaocong/p/11032509.html
Copyright © 2020-2023  润新知