服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java反射机制的简单讲解

Java反射机制的简单讲解

2021-09-23 11:55_Yoke Java教程

这篇文章主要介绍了Java反射机制的简单讲解,本文讲解了Java的高级概念反射机制,通过文字介绍案例该项概念和代码的详细展示,需要的朋友可以参考下

1. 什么是反射机制

首先大家应该先了解两个概念,编译期和运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java代码编译成jvm识别的字节码文件,而运行期指的是将可执行文件交给操作系统去执行,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
简单说,反射机制值得是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

2. java反射机制提供了什么功能?

  • 在运行时能够判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任一对象的方法
  • 在运行时创建新类对象

3.new和反射创建有什么区别呢?

new: 静态编译,在编译期就将模块编译进来,执行该字节码文件,所有的模块都被加载;

反射:动态编译,编译期没有加载,等到模块被调用时才加载;

注:spring的ioc就用到反射机制,newInstance创建。更加的通用,并且降低耦合,避免了硬编码,只需提供一个字符串就可以动态的创建。

  1. String className = readfromXMlConfig;//从xml 配置文件中获得字符串
  2.  
  3. Class c = Class.forName(className);
  4.  
  5. factory = (AInterface)c.newInstance();

举例:

有自行车,小轿车,

静态:上班将自行车放车里去上班,一定得带着,一个不能落下,

动态:将自行车放家里,交通堵塞骑自行车去,车放家里。

4. 如何通过反射调用私有对象?

  1. Field[] declaredFields = clazz.getDeclaredFields();
  2.  
  3. for (Field f : declaredFields) {
  4. System.out.println("属性的名称:" + f.getName());
  5. System.out.println("属性的类型:" + f.getType().getName());
  6. // 给属性赋值
  7. f.setAccessible(true);// 设置为私有属性可以访问

5.如何通过反射调用方法?

  1. Method m = stuClass.getMethod("show1", String.class);
  2. System.out.println(m);
  3. //实例化一个Student对象
  4. Object obj = stuClass.getConstructor().newInstance();
  5. m.invoke(obj, "刘德华");

6. class类一部分常用方法总结

  • 获取公共构造器 getConstructors()
  • 获取所有构造器getDeclaredConstructors
  • 获取包含的方法 getMethod()
  • 获取包含的属性 getField(String name)
  • 获取内部类 getDeclaredClasses()
  • 获取外部类getDeclaringClass()
  • 获取所实现的接口 getInterfaces()
  • 获取修饰符 getModifiers()
  • 获取所在包 getPackage()
  • 获取类名包含包路径 getName()

java反射的简单演示

  1. package com.fjh;
  2.  
  3. public class Student {
  4. private String name;
  5. private int age;
  6. public String getName() {
  7. return name;
  8. }
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. public int getAge() {
  13. return age;
  14. }
  15. public void setAge(int age) {
  16. this.age = age;
  17. }
  18. public Student(String name, int age) {
  19.  
  20. this.name = name;
  21. this.age = age;
  22. }
  23. public Student() {
  24. System.out.println("实例化一个对象!");
  25.  
  26. }
  27. @Override
  28. public String toString() {
  29. return "Student [name=" + name + ", age=" + age + "]";
  30. }
  31.  
  32. }
  33.  
  34. package com.fjh;
  35.  
  36. import java.lang.reflect.Constructor;
  37. import java.lang.reflect.Field;
  38. import java.lang.reflect.InvocationTargetException;
  39. import java.lang.reflect.Method;
  40.  
  41. public class ReflectTest {
  42.  
  43. public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException,
  44. SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
  45. // 普通方法创建一个对象
  46. Student stu = new Student();
  47. // 利用反射机制创建一个对象
  48. Student newInstance = Student.class.newInstance();
  49. // 通过字节码获取属性
  50. Class clazz = Student.class;
  51. // Field field = clazz.getField("name");//指定返回一个公有的属性
  52. Field field = clazz.getDeclaredField("name");
  53. System.out.println("属性的名称:" + field.getName());
  54. System.out.println("属性的类型:" + field.getType().getName());
  55.  
  56. System.out.println("---------------------");
  57. // 获取一个类中的所有属性
  58. Field[] declaredFields = clazz.getDeclaredFields();
  59. for (Field f : declaredFields) {
  60. System.out.println("属性的名称:" + f.getName());
  61. System.out.println("属性的类型:" + f.getType().getName());
  62. // 给属性赋值
  63. f.setAccessible(true);// 设置为私有属性可以访问
  64.  
  65. if (int.class == f.getType()) {
  66. f.set(newInstance, 50);
  67. } else if (String.class == f.getType()) {
  68. f.set(newInstance, "蔡徐坤");
  69. }
  70. }
  71. System.out.println("========通过直接赋值后的结果==========");
  72. System.out.println(newInstance);
  73.  
  74. System.out.println("========获取所有方法==========");
  75.  
  76. // 获取所有方法 不包括构造方法
  77. Method[] methods = clazz.getDeclaredMethods();
  78. for (Method method : methods) {
  79. String methodName = method.getName();// 参数名称
  80. int parameterCount = method.getParameterCount();// 参数个数
  81. System.out.println("方法名字:" + methodName);
  82. System.out.println("方法参数个数:" + parameterCount);
  83. Class<?>[] parameterTypes = method.getParameterTypes();
  84. // 获取每个方法的参数类型
  85. for (Class<?> class1 : parameterTypes) {
  86. System.out.println("参数类型:" + class1.getName());
  87. }
  88.  
  89. // 获取方法的返回值
  90. Class<?> returnType = method.getReturnType();
  91. System.out.println("方法的返回值为:" + returnType.getName());
  92. System.out.println("-------------------");
  93. }
  94.  
  95. // 执行获取到的 方法
  96. // 如果方法参数有多个,则需要用字节码数组来代替
  97. // Method declaredMethod = clazz.getDeclaredMethod("setName", new
  98. // Class[]{String.class,int.class});
  99. // 执行方法同样使用数组
  100. // declaredMethod.invoke(newInstance,Object[]{"mayun",20} );
  101. Method declaredMethod = clazz.getDeclaredMethod("setName", String.class);// 返回当前Class对象表示的类或接口的指定已说明的一个方法对象。
  102. declaredMethod.invoke(newInstance, "马云");
  103. System.out.println("==========设值注入=========");
  104. System.out.println(newInstance);
  105.  
  106. // 构造函数
  107. Constructor constructor = clazz.getConstructor(new Class[] { String.class, int.class });
  108. // 如何执行构造函数
  109. Object obj = constructor.newInstance(new Object[] { "周杰伦", 46 });
  110. System.out.println("==========构造注入=========");
  111. System.out.println(obj);
  112.  
  113. System.out.println("==========构造方法=========");
  114. //获取所有的构造函数
  115. Constructor[] constructors = clazz.getConstructors();
  116. for (Constructor c : constructors) {
  117. if(c.getParameterCount() != 0){
  118. Class[] parameterTypes = c.getParameterTypes();
  119. for (Class class1 : parameterTypes) {
  120. System.out.println("参数类型:"+class1.getTypeName());
  121. }
  122. System.out.println("-------------------");
  123. }else{
  124. System.out.println("无参构造");
  125. System.out.println("-------------------");
  126. }
  127. }
  128. }
  129.  
  130. }

7. 结果

Java反射机制的简单讲解

Java反射机制的简单讲解

到此这篇关于Java反射机制的简单讲解的文章就介绍到这了,更多相关Java反射机制内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_40896997/article/details/94483820

延伸 · 阅读

精彩推荐
  • Java教程Spring Cloud Gateway 如何修改HTTP响应信息

    Spring Cloud Gateway 如何修改HTTP响应信息

    这篇文章主要介绍了Spring Cloud Gateway 修改HTTP响应信息的方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    帷幄庸者13712021-10-13
  • Java教程mybatis批量新增、删除、查询和修改方式

    mybatis批量新增、删除、查询和修改方式

    这篇文章主要介绍了mybatis批量新增、删除、查询和修改方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    xuforeverlove7492022-01-24
  • Java教程浅谈java 中equals和==的区别

    浅谈java 中equals和==的区别

    这篇文章主要介绍了java 中equals和==的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小...

    独特润许多人5982021-07-21
  • Java教程Spring 6.0 将停止支持 Freemarker 和 JSP

    Spring 6.0 将停止支持 Freemarker 和 JSP

    Spring Framework 6.0 第一个里程碑版本已经发布,目前已经可以从Spring Repo获取。这里有一些新变更我们可以提前了解一下。...

    码农小胖哥12642021-12-31
  • Java教程浅谈sql_@SelectProvider及使用注意说明

    浅谈sql_@SelectProvider及使用注意说明

    这篇文章主要介绍了sql_@SelectProvider及使用注意说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    icecoola_6892021-11-04
  • Java教程mybatis调用存储过程的实例代码

    mybatis调用存储过程的实例代码

    这篇文章主要介绍了mybatis调用存储过程的实例,非常不错,具有参考借鉴价值,需要的朋友可以参考下...

    动力节点11732021-01-25
  • Java教程二进制中1的个数

    二进制中1的个数

    这篇文章介绍了二进制中1的个数,有需要的朋友可以参考一下 ...

    java之家2662019-10-15
  • Java教程Java开发常见异常及解决办法详解

    Java开发常见异常及解决办法详解

    这篇文章主要介绍了java程序常见异常及处理汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考...

    cutercorley12252021-12-18