目录

基本概念

代码与实例


基本概念

反射的进一步理解:
将类的各个组成部分封装为其他对象(将一个类的组成部分封装为其他对象)
就是反射。

Java代码经历的三个阶段:
1. 写好代码.java后使用javac,编译为字节码文件:xxx.class
    这个阶段称之为source源代码阶段。

3. 当程序要new一个对象时
    这个阶段称之为Runtime运行时阶段

2. 把字节码文件.class加载进内存里面(使用类加载器ClassLoader)
在内存里面会存在一个对象用于描述字节码文件。这个对象为Class对象。
所以java里面有个Class类。专门用来搞这个字节码文件的
如:
成员变量(Fields)、构造方法(Constructor)、成员方法(Method)
这个阶段称之为Class类对象阶段

第三阶段都是同过第二阶段创建起来的。第二个阶段需要第一个阶段。

反射好处:
          1. 在程序运行过程中操作这些对象。(IDEA这个程序的 某个对象方法的提示,就是反射)
          2. 可以解耦。提高程序可扩展性。

获取Class对象的方式:
有3种方式,对应java代码经历的3个阶段;
第一个阶段只有.class字节码文件,并没有在内存中,要把.class加载到内存中生成对象。对应的API为:Class.forName("全类名") 返回class对象;
第二个阶段:这个.class字节码文件已经到内存了,这个时候,只要获取他就可以了,类名.class,这种方式。
第三个阶段:在Runtime时,已经有对象了,这个时候只要 对象.getClass()就可以了。这个getClass()类是在Object里面
的。

总结下:
          1.Class.forName("全类名");将字节码文件加载到内存,返回class对象。
          2.类名.class;通过类名的属性class获取。
          3.对象.getClass();getClass()方法在Object类中定义

代码与实例

如下代码:

Person.java

package Object;public class Person {private String name;private Integer age;public Person(String name, Integer age) {this.name = name;this.age = age;}public Person(){}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

Main1.java

import Object.Person;public class Main1 {public static void main(String[] args) throws ClassNotFoundException {//全类名Class cls1 = Class.forName("Object.Person");System.out.println(cls1);//类名.classClass cls2 = Person.class;System.out.println(cls2);//对象.getClass()Person p = new Person();Class cls3 = p.getClass();System.out.println(cls3);//比较下对象:System.out.println(cls1 == cls2);System.out.println(cls1 == cls3);}
}

程序运行截图如下:

结论:
同一个字节码文件.class在一次程序运行过程中,只会被加载一次,不论通过哪种方式获取的class对象都是同一个。
第一种方式,多用于配置文件中,读取文件,加载类
第二种方式,多用于参数的传递;
第三种方式,多用于对象的获取字节码

下面是

Class对象功能:
1.获取成员变量;
          Field[] getFields()
          Field getField(String name)
          Field[] getDeclaredFields()
          Field getDeclaredField(String name)
2.获取构造方法;
          Constructor<?>[] getConstructors()
          Constructor<T> getConstructor(类<?>... parameterTypes)
          Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
          Constructor<?>[] getDeclaredConstructors()
3.获取成员方法;
          Method[] getMethods()
          Method[] getMethod(String name, 类<?>... parameterTypes)
          Method[] getDeclaredMethods()
          Method getDeclaredMethod(String name, 类<?>... parameterTypes)
4.获取类名;
          String getName()

下面先给出变量名的实例

Person.java

package Object;public class Person {private String name;private Integer age;public String a;protected String b;String c;private String d;public Person(String name, Integer age) {this.name = name;this.age = age;}public Person(){}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", a='" + a + '\'' +", b='" + b + '\'' +", c='" + c + '\'' +", d='" + d + '\'' +'}';}
}

Main2.java

import Object.Person;import java.lang.reflect.Field;public class Main2 {public static void main(String[] args) throws Exception {//Field[] getFields()获取所有public修饰的成员变量Class aClass = Class.forName("Object.Person");Field[] fields = aClass.getFields();for(Field field : fields){System.out.println(field);}//获取及设置a的值Field a = aClass.getField("a");Person person = new Person();Object value = a.get(person);System.out.println("the a is : " + value);a.set(person, "你妹");System.out.println(person);System.out.println("----------华丽的分割线----------");//Field getDeclaredField(String name)Field[] declaredFields = aClass.getDeclaredFields();for(Field field : declaredFields){System.out.println(field);}//忽略修饰符暴力反射,设置值Field d = aClass.getDeclaredField("d");d.setAccessible(true);d.set(person, "猪小明");System.out.println(person);}
}

运行截图如下:

下面是关于构造函数的反射:

Person还是与上面的一样。

import Object.Person;import java.lang.reflect.Constructor;public class Main3 {public static void main(String[] args) throws Exception {Class personClass = Person.class;Constructor constructor = personClass.getConstructor(String.class, Integer.class);System.out.println(constructor);//创建对象Object p = constructor.newInstance("王二麻子", 99);System.out.println(p);System.out.println("----------华丽的分割线----------");Constructor constructor2 = personClass.getConstructor();Object p2 = constructor2.newInstance();System.out.println(p2);}
}

程序运行截图如下:

下面是获取成员方法的实例。

Person.java

package Object;public class Person {private String name;private Integer age;public String a;protected String b;String c;private String d;public Person(String name, Integer age) {this.name = name;this.age = age;}public Person(){}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", a='" + a + '\'' +", b='" + b + '\'' +", c='" + c + '\'' +", d='" + d + '\'' +'}';}public void eat(){System.out.println("eat... ...");}//带参数的public void eat(String food){System.out.println("eat... ..." + food);}
}

Main4.java

import Object.Person;import java.lang.reflect.Method;public class Main4 {public static void main(String[] args) throws Exception {Class personClass = Person.class;//获取指定名称的方法Method eat = personClass.getMethod("eat");Person p = new Person();eat.invoke(p);System.out.println("----------华丽的风格线----------");Method eat1 = personClass.getMethod("eat", String.class);eat1.invoke(p, "西北风");//获取所有Public修饰的方法Method[] methods = personClass.getMethods();for(Method method : methods){System.out.println(method);String name = method.getName();System.out.println(name);//method.setAccessible(true);}}
}

程序运行截图如下:

下面是关于获取类名的实例:

Main5.java

import Object.Person;public class Main5 {public static void main(String[] args){Class personClass = Person.class;System.out.println(personClass.getName());}
}

程序运行截图如下:

import Object.Person;public class Main5 {public static void main(String[] args){Class personClass = Person.class;System.out.println(personClass.getName());}
}

程序运行截图如下:

下面来仿一个案例,像Spring Boot那样的通过配置application.properties既可以调用相应的类,和函数

这里应用到的就是反射

Main6.java

import Object.Person;import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;public class Main6 {public static void main(String[] args) throws Exception {/**** 加载配置文件*      创建Properties对象*      加载配置文件,转换为集合*      获取class目录下的配置文件*/Properties pro = new Properties();ClassLoader classLoader = Person.class.getClassLoader();InputStream resourceAsStream = classLoader.getResourceAsStream("application.properties");pro.load(resourceAsStream);//配置文件中定义的数据String className = pro.getProperty("className");String methodName = pro.getProperty("methodName");//加载该类到内存Class aClass = Class.forName(className);Object o = aClass.newInstance();//获取方法并执行Method method = aClass.getMethod(methodName);method.invoke(o);}
}

通过这种配置文件,即可调用对应的类和方法:

程序运行截图如下:

源码打包下载地址:

https://github.com/fengfanchen/Java/tree/master/ReflectDemo

Java工作笔记-对反射的进一步理解相关推荐

  1. Qt工作笔记-对setupUi(this)进一步理解

    今天工作中,在构造函数中忘记了调用setupUi,使得程序中某些指针异常. 如下图的程序,当什么不做的时候,界面是这样的: 当把ui->setupUi(this)注释掉后 这里先看下setupU ...

  2. Java学习笔记 7-20 反射

    反射 1. 反射机制的概念 反射机制就是在程序运行时,可以动态获取任意一个类及其所有属性和方法并创建对象,可以对任意一个对象调用其任意方法和属性. 2. 反射机制的作用 在程序运行时获取任意类的对象, ...

  3. C++工作笔记-对继承的进一步认识

    这篇博文将说明我对继承的进一步理解. 比如在图形碰撞的时候,如果能让他继承一个类,那个类设置一个flag,就可以对不同的图形进行不同的碰撞分析,那么这里就可以用父类指针,去指向子类,然后读取子类里面和 ...

  4. Java工作笔记-注解的进一步理解

    目录 基本概念 代码与实例 基本概念 注解:说明程序,给计算机看的. 注释:给程序员看的. 作用分类: 编写文档:通过代码里标识的注解生成文档javadoc(生成doc文档) 代码分析:通过代码里标识 ...

  5. Java工作笔记-枚举类型反射

    这里枚举类型有自己的反射方式: 这里我先总结下逻辑: 1. 通过getEnumConstatnts返回目前枚举中存在的对象. 2. 通过getMehod获取方法. 3. 最后用这个对象调用其方法. 程 ...

  6. Java工作笔记-类型转换的一种思路(前后端分离、反射)

    这里主要是一种思路,前端可能会发送ajax请求.这个内容是json数据.这里面的数据可能全部是以字符串为主. 通常可以通过反射进行改变,如下的代码: 如下要转换成这些类型 不然当时候赋值的时候就麻烦了 ...

  7. 【Java书笔记】:《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第2部分-自动内存管理,第3部分-虚拟机执行子系统,第5部分-高效并发

    作者:周志明 整理者GitHub:https://github.com/starjuly/UnderstandingTheJVM 第2部分-自动内存管理 第2章 Java内存区域与内存溢出异常 2.2 ...

  8. Java工作笔记/Java面试题/Java八股文/Java常用API

    码农工具包 hutool工具 hutool工具类判断各种类型数据 <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --& ...

  9. Java高新技术笔记:反射、多线程、泛型、枚举、javaBean、代理

    1.IDE: Integrated Development Environment 2.集成开发环境两个主流:Eclipse和netBeans 3.preference: 偏爱 4.Compiler: ...

最新文章

  1. NBT:超高速细菌基因组检索技术
  2. 当当大促的额外优惠来啦!160 买 400的书!搓搓搓~
  3. Maven之依赖管理
  4. msdn中C#中常用词汇概念(转帖)
  5. 项目管理(7):备战pmp
  6. 服务器重装后怎么装系统,服务器如何安装系统,小编教你如何安装
  7. win7 微软语音服务器,win7 TTS修复工具(微软tts语音引擎修复)
  8. CCF201503-5 最小花费(100分解题链接)
  9. vue上传图片时,console.log()图片信息遇到的坑
  10. 整理了一些计算机毕设源码+论文 免费分享给大家
  11. 搭建Kangle+EasyPanel+WHMCS实时开通付费虚拟空间
  12. 高级shell编程笔记(第十二章 外部过滤器,程序和命令)
  13. 警务通、停车场收费终端集成手机拍照车牌识别SDK,通过手机就可实现快速便捷的出入口系统管理...
  14. think python 第9章 case study:word play
  15. 如何在ipone自带邮件上添加网易邮箱
  16. 程序员找工作经历,一个人在上海工作的艰辛
  17. 114号和116号元素诞生记:验证历时4年多
  18. 如何求一个关系模式的候选码
  19. webrtc android web,WebRTC Android版本编译
  20. 鼠标滚轮失灵解决方法2种实测

热门文章

  1. 穿戴式设备的用户体验设计-郝华奇
  2. Android:ListView
  3. 从经理的角度看领域设计
  4. C++中宏与内联函数
  5. 5分钟教零基础开发一张驾驶舱(附驾驶舱工具及模板)
  6. 助推曲烟数字化转型升级,开展生产业务数字化
  7. 媒体没谈到的企业即时通讯软件
  8. Visual Studio 调试器---Visual Studio 调试器
  9. 到底什么培训适合你?
  10. 你是菜鸡是有原因的 谈谈提问的艺术