Android

对Java反射的理解与应用

2018-01-16  本文已影响208人  VerseWang

        18年过去半个月了,说说最近身边发生的事,我妈老喜欢和我爸吵架,都六十多岁的人了,还在吵架,我爸是一个老实人,她是一个个性很强的人,而且不可理喻,但是呢,我是他们的儿子,儿不嫌母丑,我没有讨厌我妈的意思,可能是吃药的原因吧,对脑子有点影响,我总觉得我妈想不过来问题,我妈老喜欢找我把吵架,昨天给她打电话,我跟她说,您少生点气,现在全身都是病,再生气,过几天又要跑医院了,您还没抱孙子呢。跟她说,她就是听不进去,还是一个劲的说我爸,只怪我现在没能力,有能力的话,就要把他们分开,他们两分开就吵不了架了,有什么是可以商量的嘛,干嘛吵架呀,唉,我是在他们吵架中长大的,深深知道为孩子的成长很不好,为了我未来的孩子的健康成长,我尽量不要跟我未来的老婆吵架,各位网友也是记住喔,两夫妻吵架对小孩的影响很不好,少吵架,和气生财嘛。

最近在学习Retrofit,里面有很多注解,对注解不是很了解,二话不多,就在网上看注解的使用,但注解运用到了反射,又重学了一边反射,反射是Java基础,用的虽然不算多,但为了更深刻的理解,我就通过笔记记下来。

说到反射机制,先来说说Java虚拟机:

1.Java虚拟机

Java虚拟机是运行所有Java程序的抽象计算机,是Java语言的运行环境,在其上面运行Java代码编译后的字节码程序,java虚拟机实现了平台无关性。

1.1java虚拟机及其结构

java垃圾回收不需要程序员手动操作,我们经常需要关注的是java虚拟机,java虚拟机承载着程序从源码到运行的全部工作。

Java虚拟机是可运行Java代码的假想计算机,有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统,可以执行 Java 的字节码程序。Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。

对于 JVM 的基本结构,我们可以从下图可以大致了解:

图片来自Java 虚拟机体系结构

2.程序的运行过程

从源文件创建到程序运行,Java程序要经过两大步骤:编译,运行;1、源文件由编译器编译成字节码(ByteCode)  2、字节码由java虚拟机解释运行。

第一步(编译): 创建完源文件之后,程序会被编译器编译为.class文件。Java编译一个类时,如果这个类所依赖的类还没有被编译,编译器就会先编译这个被依赖的类,然后引用,否则直接引用。。编译后的字节码文件格式主要分为两部分:常量池和方法字节码。

    第二步(运行):java类运行的过程大概可分为两个过程:1、类的加载  2、执行。

3.类的加载

java程序经过编译后形成*.class文件。通过类加载器将字节码(*.class)加载入JVM的内存中。JVM将类加载过程分成加载,连接,初始化三个阶段,其中连接阶段又可分为验证,准备,解析三个阶段。

4.Class对象的获取

//第一种方式 通过对象getClass方法

Person person =new Person();

Class class1 = person.getClass();

//第二种方式 通过类的class属性

class1 = Person.class;

//第三种方式 通过Class类的静态方法——forName()来实现

try {

class1 = Class.forName("com.whoislcj.reflectdemo.Person");

} catch (ClassNotFoundException e) {

    e.printStackTrace();

}

5.反射

5.1构造方法反射

Classclazz =Class.forName("photogallery.javademo.Bean");

Constructor[] conArray = clazz.getDeclaredConstructors();//获取所有的构造方法(不管是私有、受保护、默认、公有)

Constructor[] conArray1 = clazz.getConstructors();//获取public的构造方法

for(Constructor c : conArray){

System.out.println(c);

}

//反射构造方法

Constructor con = clazz.getDeclaredConstructor(String.class);

con.setAccessible(true);//暴力访问(忽略掉访问修饰符)

//反射Bean(String name)

Bean bean = (Bean)con.newInstance("wangyang");

System.out.println(bean.getName());

5.2变量反射

Classclazz =Class.forName("photogallery.javademo.Bean");

//        Field[] field = clazz.getFields();

        Field field = clazz.getDeclaredField("name");

        field.setAccessible(true);

        System.out.println(" qwqwwwqq " + clazz.getConstructors().length);

        Object obj = clazz.getConstructor(String.class).newInstance("haha");

        field.set(obj, "wangyang");

        Bean bean = (Bean) obj;

        System.out.println("  " + bean.getName());

5.3函数反射

Classclazz =Class.forName("photogallery.javademo.Bean");

Method method = clazz.getDeclaredMethod("setName", String.class);

Object obj = clazz.getConstructor().newInstance();

method.invoke(obj, "wangyang");

Bean bean = (Bean) obj;

System.out.println("  " + bean.getName());

好记性不如乱笔头,把他记下来,加深印象

上一篇下一篇

猜你喜欢

热点阅读