java中的反射机制

前言:

​相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有个开源框架jOOR相信很多人都用过,不过我们还是要学习反射的基础语法,这样才能自己写出优秀的框架,当然这里所讲的反射技术,是学习Android插件化技术、Hook技术等必不可少的!

概述:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

以上的总结就是什么是反射
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
如图是类的正常加载过程:反射的原理在与class对象。
熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

主要作用

通过反射可以使程序代码访问装载到JVM 中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息

常用方法

(1)创建Student类

package cn.tedu.reflection;//测试 反射public class Student { public String name = "皮皮霞"; public int age = 22 ;    //提供构造方法-右键-generate...constructor...    public Student() {    }    public Student(String name) {        this.name = name;    }    public Student(int age) {        this.age = age;    }    public Student(String name, int age) {        this.name = name;        this.age = age;    }`public void show(){        System.out.println("show()...");    }    public void test(String n){        System.out.println("test()..."+n);    }    //为了能查看属性值,而不是地址值,提供重写的toString()    //右键-generate...toString()-ok    @Override    public String toString() {        return "Student{" +                "name='" + name + ''' +                ", age=" + age +                '}';    }}

(2)创建测试类

package cn.tedu.reflection; import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Arrays;//测试 反射public class Test1_Reflect {    public static void main(String[] args) throws Exception {        //method();//通过反射的技术,获取Class对象//        method2();//通过反射的技术,获取类中的所有构造方法//        method3();//通过反射的技术,获取成员方法//        method4();//通过反射的技术,获取成员变量        method5();//通过反射的技术,创建实例    }    //通过反射的技术,创建实例    private static void method5() throws Exception {        //1,获取Class对象        Class<Student> clazz = Student.class;        //2,创建实例        //newInstance()--会触发构造方法--触发无参构造        Student s = clazz.newInstance();        //s = Student{name='皮皮霞', age=22}        System.out.println("s = " + s);         //3,需求:可以触发含参构造吗?可以-但是你得指定想要触发哪个含参构造        // --参数是class对象类型,和含参构造的参数类型匹配        //public Student(String name){} -- new Student("jack");        Constructor<Student> c = clazz.getConstructor(String.class);        Student s2 = c.newInstance("jack");        //s2 = Student{name='jack', age=22}        System.out.println("s2 = " + s2);    }    //通过反射的技术,获取成员变量    private static void method4() throws ClassNotFoundException {        //1,获取Class对象        Class<?> clazz = Class.forName("cn.tedu.reflection.Student");        //2,获取成员变量--!!!!只能获取public的!!!!        Field[] fs = clazz.getFields();        //3,遍历数组,获取每个Field        for (Field f : fs) {            //获取变量名            System.out.println( f.getName() );            //获取变量类型            System.out.println( f.getType().getName() );        }    }    //通过反射的技术,获取成员方法    private static void method3() {        //1,获取Class对象        Class clazz = Student.class;        //2,获取成员方法们        Method[] ms = clazz.getMethods();        //3,遍历数组,获取每个Method        for (Method m : ms) {            //获取方法名            System.out.println(m.getName());            //获取方法参数            Class<?>[] cs = m.getParameterTypes();            System.out.println( Arrays.toString(cs) );        }    }    //通过反射的技术,获取类中的构造方法    private static void method2() {        //1,获取Class对象        Class<Student> clazz = Student.class;        //2,获取构造方法们        Constructor<?>[] cs = clazz.getConstructors();        //3,foreach循环获取每个构造方法        for (Constructor<?> c : cs) {            //获取构造方法名            System.out.println(c.getName());            //获取构造方法的参数            Class<?>[] cs2 = c.getParameterTypes();            System.out.println(Arrays.toString(cs2));        }    }    //通过反射的技术,获取Class对象//三种方式    private static void method() throws ClassNotFoundException {//        -- static Class<?> forName(String className)--参数是类的全路径        Class<?> clazz = Class.forName("java.lang.Object");//        -- 类名.class        Class<String> clazz2 = String.class;//        -- 对象.getClass()--泛型上限,最大是String类型,约束了元素的类型<=String类型        Class<? extends String> clazz3 = new String().getClass();         System.out.println("clazz = " + clazz);        System.out.println("clazz2 = " + clazz2);        System.out.println("clazz3 = " + clazz3);    }}

暴力反射

暴力的获取类中的私有资源顺便获取公开的。
暴力反射和普通反射的反射原理是一样的,都是拿到.class文件中的所有数据并封装成Class对象,通过各种方法来操作数据,只不过是换了一套API

反射机制的优缺点

优点:

反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;反射是其它一些常用语言,如C、C++、Fortran 或者Pascal等都不具备的

缺点:

  • 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。

  • 使用反射会模糊程序内部逻辑:程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。

(0)

相关推荐

  • Java学习——35、子类的构造方法

    本文接上篇--34.类的继承. 子类可以继承父类的除了构造方法以外的所有成员,在子类创建对象时,必须对父类的变量进行初始化.但构造方法是不被继承的,故要在子类当中调用父类的构造方法. 如果子类中没有显 ...

  • 【Java面试题第七期】一文回答面试中常见反射问题?

    java反射的作用 反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意个对象,都能够调用它的任意一个方法.在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信 ...

  • 吊打面试官系列:说说反射的用途及实现?

    反射是什么? 反射是Java程序开发语言的特征之一,它允许动态地发现和绑定类.方法.字段,以及所有其他的由于有所产生的的元素.通过反射,能够在需要时完成创建实例.调用方法和访问字段的工作. 反射机制主 ...

  • Java基础之三个修饰符

    三个关键字 抽象的(abstract) 静态(static) 最终的(final) 一.抽象 1.1 什么是抽象 似是而非的,像却又不是:具备某种对象的特征,但不完整. 二. 抽象的(abstract ...

  • 子类的构造方法

    子类可以继承父类的除构造方法和析构方法以外的所有成员,在子类创建对象时,必须对父类的变量进行初始化.但构造方法是不被继承的,故要在子类当中调用父类的构造方法. 如果子类中没有显式调用父类的构造方法,J ...

  • 高级开发必须理解的Java中SPI机制

    本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践.学习开源项目提供参考. 1 SPI是什么 SPI全称Service Provider Interface ...

  • 15个经典面试问题,java中异常处理机制的原理和应用

    微服务架构 第1章 微服务概述 什么是微服务 常见的微服务组件 常用的微服务框架 微服务架构设计模式 如何实施微服务 从微服务的起源和现实业务的角度探讨微服务 第2章 微服务设计原则 设计原则之分层架 ...

  • Java反射机制是什么?

    Java反射机制是Java语言的一个重要特性.在学习Java反射机制前,大家应该先了解两个概念,编译期和运行期. 编译期是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Jav ...

  • Java反射机制API

    实现Java反射机制的类都位于java.lang.reflect包中,java.lang.Class类是Java反射机制API中的核心类.本节将从这两个方面讲解Java反射机制API. java.la ...

  • Android插件化开发基础之Java反射机制研究

    一.获得Class对象 Class<?> c = Class.forName("classname"); 抛出ClassNotFoundException 二.获得实现 ...

  • Java 中的关键字

    Java 中有多少个关键字,有大小写之分吗? Java 中有 48 个关键字在使用 + 两个保留关键字未使用,共 50 个关键字. Java 关键字全部都由是小写组成. Java 中保留关键字分别是哪 ...

  • Java中的匿名内部类

    一.匿名内部类 之前的所有类都有自己的名字,但是有时候如果某个接口的实现类(或者某个父类的子类)只需要使用一次,此时这样的类如果我们单独定义出来则需要单独为其创建一个"*.java" ...

  • Java中的方法内部类

    一:方法内部类 就是在方法中直接定义一个内部类,之后直接使用这个内部类对象的方法,你作为语法 了解就行了. DEMO:方法中定义内部类     以上是在方法中定义了一个内部类,方法中的内部类能访问方法 ...