Java反射机制的简单讲解

作者:_Yoke 时间:2023-12-12 20:49:13 

🌱1. 什么是反射机制?

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

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

  • 在运行时能够判断任意一个对象所属的类

  • 在运行时构造任意一个类的对象

  • 在运行时判断任意一个类所具有的成员变量和方法

  • 在运行时调用任一对象的方法

  • 在运行时创建新类对象

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

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

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

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


String className = readfromXMlConfig;//从xml 配置文件中获得字符串

Class c = Class.forName(className);

factory = (AInterface)c.newInstance();

举例:

有自行车🚲,小轿车🚗,

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

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

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


Field[] declaredFields = clazz.getDeclaredFields();

for (Field f : declaredFields) {
System.out.println("属性的名称:" + f.getName());
System.out.println("属性的类型:" + f.getType().getName());
// 给属性赋值
f.setAccessible(true);// 设置为私有属性可以访问

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


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

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

  • 获取公共构造器 getConstructors()

  • 获取所有构造器getDeclaredConstructors

  • 获取包含的方法 getMethod()

  • 获取包含的属性 getField(String name)

  • 获取内部类 getDeclaredClasses()

  • 获取外部类getDeclaringClass()

  • 获取所实现的接口 getInterfaces()

  • 获取修饰符 getModifiers()

  • 获取所在包 getPackage()

  • 获取类名包含包路径 getName()

java反射的简单演示


package com.fjh;

public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {

this.name = name;
this.age = age;
}
public Student() {
System.out.println("实例化一个对象!");

}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}

}

package com.fjh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest {

public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException,
SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
// 普通方法创建一个对象
Student stu = new Student();
// 利用反射机制创建一个对象
Student newInstance = Student.class.newInstance();
// 通过字节码获取属性
Class clazz = Student.class;
// Field field = clazz.getField("name");//指定返回一个公有的属性
Field field = clazz.getDeclaredField("name");
System.out.println("属性的名称:" + field.getName());
System.out.println("属性的类型:" + field.getType().getName());

System.out.println("---------------------");
// 获取一个类中的所有属性
Field[] declaredFields = clazz.getDeclaredFields();
for (Field f : declaredFields) {
System.out.println("属性的名称:" + f.getName());
System.out.println("属性的类型:" + f.getType().getName());
// 给属性赋值
f.setAccessible(true);// 设置为私有属性可以访问

if (int.class == f.getType()) {
f.set(newInstance, 50);
} else if (String.class == f.getType()) {
f.set(newInstance, "蔡徐坤");
}
}
System.out.println("========通过直接赋值后的结果==========");
System.out.println(newInstance);

System.out.println("========获取所有方法==========");

// 获取所有方法 不包括构造方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
String methodName = method.getName();// 参数名称
int parameterCount = method.getParameterCount();// 参数个数
System.out.println("方法名字:" + methodName);
System.out.println("方法参数个数:" + parameterCount);
Class<?>[] parameterTypes = method.getParameterTypes();
// 获取每个方法的参数类型
for (Class<?> class1 : parameterTypes) {
System.out.println("参数类型:" + class1.getName());
}

// 获取方法的返回值
Class<?> returnType = method.getReturnType();
System.out.println("方法的返回值为:" + returnType.getName());
System.out.println("-------------------");
}

// 执行获取到的 方法
// 如果方法参数有多个,则需要用字节码数组来代替
// Method declaredMethod = clazz.getDeclaredMethod("setName", new
// Class[]{String.class,int.class});
// 执行方法同样使用数组
// declaredMethod.invoke(newInstance,Object[]{"mayun",20} );
Method declaredMethod = clazz.getDeclaredMethod("setName", String.class);// 返回当前Class对象表示的类或接口的指定已说明的一个方法对象。
declaredMethod.invoke(newInstance, "马云");
System.out.println("==========设值注入=========");
System.out.println(newInstance);

// 构造函数
Constructor constructor = clazz.getConstructor(new Class[] { String.class, int.class });
// 如何执行构造函数
Object obj = constructor.newInstance(new Object[] { "周杰伦", 46 });
System.out.println("==========构造注入=========");
System.out.println(obj);

System.out.println("==========构造方法=========");
//获取所有的构造函数
Constructor[] constructors = clazz.getConstructors();
for (Constructor c : constructors) {
if(c.getParameterCount() != 0){
Class[] parameterTypes = c.getParameterTypes();
for (Class class1 : parameterTypes) {
System.out.println("参数类型:"+class1.getTypeName());
}
System.out.println("-------------------");
}else{
System.out.println("无参构造");
System.out.println("-------------------");
}
}
}

}

🌱7. 结果

Java反射机制的简单讲解

Java反射机制的简单讲解

来源:https://blog.csdn.net/qq_40896997/article/details/94483820

标签:Java,反射机制
0
投稿

猜你喜欢

  • C#多线程学习之(四)使用线程池进行多线程的自动管理

    2021-07-17 10:04:43
  • Android 中在有序广播中添加自定义权限的实例

    2021-08-10 05:09:35
  • Diycode开源项目实例搭建上拉加载和下拉刷新的Fragment

    2023-06-17 01:13:03
  • Android解决ScrollView下嵌套ListView和GridView中内容显示不全的问题

    2023-09-26 23:32:58
  • Android返回键功能的实现方法

    2021-10-01 12:54:53
  • 如何在Unity中检测死循环和卡死

    2023-12-18 00:55:17
  • Android提高之MediaPlayer音视频播放

    2021-05-29 08:44:37
  • Android自定义StepView仿外卖配送进度

    2022-07-30 01:34:35
  • Java的Struts框架中登陆功能的实现和表单处理器的使用

    2022-05-20 23:44:45
  • c# base64转字符串实例

    2021-06-25 01:47:54
  • thymeleaf实现前后端数据交换的示例详解

    2023-04-18 12:02:54
  • javamail 发送邮件的实例代码分享

    2021-12-22 15:10:47
  • IDEA中的maven没有dependencies解决方案

    2021-08-01 11:58:50
  • Android SlidingMenu使用和示例详解

    2023-10-28 08:06:59
  • Spring Boot下的Job定时任务

    2021-10-23 05:16:14
  • 详解Java关键字final

    2023-11-29 09:10:27
  • springboot集成mybatis plus和dynamic-datasource注意事项说明

    2023-12-05 03:54:21
  • Java线程安全和锁Synchronized知识点详解

    2023-01-23 03:59:38
  • c# 进程和线程的区别与联系

    2023-05-04 23:18:36
  • Jpa Specification如何实现and和or同时使用查询

    2023-10-17 20:49:38
  • asp之家 软件编程 m.aspxhome.com