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. 结果
来源:https://blog.csdn.net/qq_40896997/article/details/94483820


猜你喜欢
- 为了方便客户抓取Log,现通过TCP协议连接指定服务器,传输指定内容,定义指定目录,IP,PORT字段接收参数。直接上代码 public s
- 本文实例讲述了Android实现整理PackageManager获取所有安装程序信息的方法。分享给大家供大家参考,具体如下:List<
- 这篇文章主要介绍了java的package和import机制原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- 本文实例讲述了Android开发中ProgressDialog简单用法。分享给大家供大家参考,具体如下:网上一般对进度条的示例都是如何显示,
- 一:背景1. 讲故事周五下午运营反馈了一个紧急bug,说客户那边一个信息列表打不开,急需解决,附带的日志文件也发过来了,看了下日志大概是这样
- 对于ViewPager 广告页这个功能很多APP都有这个功能在网上也看过一些资料,我就在这把我自己完整的实现方法写出来吧基础的ViewPag
- 本文实例讲述了Android播放器MediaPlayer实现均衡器效果。分享给大家供大家参考,具体如下:这几天在系统学习Android官方A
- 概述spirng-aop模块是Spring框架中的核心模块,虽然Spring Ioc container并不依赖AOP,但AOP给Ioc的实
- Java 编程语言中时间的处理类有 Date类与 Calendar类。目前官方不推荐使用 Date类,因为其不利于国际化;而是推荐使用 Ca
- 一、使用Json.NetJson.Net是支持序列化和反序列化DataTable、DataSet、Entity Framework和Enti
- (1). 和反射+泛型有关的接口类型java.lang.reflect.Type:java语言中所有类型的公共父接口java.lang.re
- 本文实例为大家分享了java使用poi导出图片到Excel的具体代码,供大家参考,具体内容如下代码实现Controller/** * 导出志
- 对于从事Android开发的人来说,遇到ANR(Application Not Responding)是比较常见的问题。一般情况下,如果有A
- 前言你一定会好奇:“老周,你去哪开飞机了?这么久没写博客了。”老周:“我买不起飞机,开了个铁矿,挖了一年半的石头。谁知铁矿垮了,压死了几条蜈
- 写在最前面上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考。Demo是在我上次写的
- 开发环境:IntelliJ IDEA 2019.2.2Spring Boot版本:2.1.8一、发布REST服务1、IDEA新建一个名称为r
- 首先我们上图: xml的代码如下,用于编写按钮:<?xml version="1.0" encoding
- 在平常工作中我们经常会遇到maven引用的jar包冲突的事情,这时候我们就需要找出冲突的包,并将低版本或者缺少某些方法的jar给剔除掉。这个
- 1. 前言Spring最重要的一个概念当属Bean了,我们写的Controller、Service、Dao凡是加了对应注解交给Spring管
- 本文实例讲述了Android软键盘弹出时的界面控制方法。分享给大家供大家参考,具体如下:有时候androidactivity弹出软键盘后布局