Java反射机制的简单讲解

 更新时间:2021年07月01日 09:24:19   作者:_Yoke  
这篇文章主要介绍了Java反射机制的简单讲解,本文讲解了Java的高级概念反射机制,通过文字介绍案例该项概念和代码的详细展示,需要的朋友可以参考下

🌱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反射机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot 2.x 整合Lombok的方法示例

    SpringBoot 2.x 整合Lombok的方法示例

    Spring Boot是非常高效的开发框架,lombok是一套代码模板解决方案,将极大提升开发的效率,这篇文章主要介绍了SpringBoot 2.x 整合Lombok的方法示例,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • 如何通过idea给web项目打war包

    如何通过idea给web项目打war包

    这篇文章主要介绍了如何通过idea给web项目打war包问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Springboot整合zookeeper实现对节点的创建、监听与判断的案例详解

    Springboot整合zookeeper实现对节点的创建、监听与判断的案例详解

    这篇文章主要介绍了基于Springboot整合zookeeper实现对节点的创建、监听与判断,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Spring Boot中Reactor模型的基本概念和最佳实践

    Spring Boot中Reactor模型的基本概念和最佳实践

    Reactor模型是一种基于事件驱动和非阻塞IO的编程模型,用于处理并发和异步操作,本文将介绍Spring Boot中使用Reactor模型的基本概念和最佳实践,帮助读者更好地理解如何利用这一强大的工具来构建现代化的Java应用程序,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • 通过实例解析Java class文件编译加载过程

    通过实例解析Java class文件编译加载过程

    这篇文章主要介绍了通过实例解析Java class文件编译加载过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Mybatis-Plus中的selectByMap使用实例

    Mybatis-Plus中的selectByMap使用实例

    Mybatis-Plus来对数据库进行增删改查时,将里面的函数试了个遍,接下来我就将使用selectByMap函数的简单测试实例写出来,方便没有使用过的朋友们快速上手,感兴趣的可以了解一下
    2021-11-11
  • Spring  AOP的两种使用方法

    Spring  AOP的两种使用方法

    这篇文章主要介绍了Spring AOP的两种使用方法,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • SpringCloud Feign多参数传递及需要注意的问题

    SpringCloud Feign多参数传递及需要注意的问题

    这篇文章主要介绍了SpringCloud Feign多参数传递及需要注意的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • java程序中date类型比较大小问题

    java程序中date类型比较大小问题

    在Java编程中,经常会遇到需要比较两个日期大小的场景,Java的Date类提供了几种方法来比较日期,包括compareTo()、before()、after()和getTime(),compareTo()方法通过返回值判断两个日期的先后;before()方法判断当前日期是否在指定日期之前
    2024-11-11
  • SpringBoot测试时卡在Resolving Maven dependencies的问题

    SpringBoot测试时卡在Resolving Maven dependencies的问题

    这篇文章主要介绍了SpringBoot测试时卡在Resolving Maven dependencies的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02

最新评论