BCSP-玄子Share-Java框基础_反射

一、反射

1.1 反射介绍

Java反射:在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用

1.1.1 Java 程序的运行过程

在这里插入图片描述

1.1.2 反射及其作用

反射是指能够在运行时,观察并修改自己运行时(Runtime)行为的特性 Java 反射机制主要提供了以下的一些功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的属性和方法
  • 在运行时调用任意一个对象的方法

1.2 反射技术常用 API

  • java.lang.Class 类可获取类和类的成员信息
  • java.lang.reflect.Constructor 类可调用类的构造方法
  • java.lang.reflect.Field 类可访问类的属性
  • java.lang.reflect.Method 类可调用类的方法

1.2.1 使用反射的基本步骤

  1. 导入 java.lang.reflect.*
  2. 获得需要操作的类的 java.lang.Class 对象
  3. 调用Class的方法获取 Field、Method 等对象
  4. 使用反射 API 操作实例成员

1.3 反射的入口类 Class

Class 类是 Java 反射机制的起源和入口

  • 每个类都有自己向关的 Class 对象
  • 提供了获取类信息的相关方法

Class 类存放类的结构信息

  • 类名
  • 父类﹑接口
  • 构造方法﹑方法﹑属性
  • 注解
  • ……

1.3.1 获取 Class 实例

获取 Class 实例的常用方式

// 方法1:对象.getClass()
Class clazz = new Student().getClass();
// 方法2:类.class
Class clazz = Student.class;
// 方法3:Class.forName()
Class clazz = Class.forName("xxx.xxx.Student");
// 方法4:基本数据类型包装类.TYPE
Class<Integer> clazz = Integer.TYPE;

1.4 反射获取信息

1.4.1 获取类的基本信息

方法说明
String getName()以字符串形式返回该类型的名称
String getSimpleName()以字符串形式返回该类型的简称
Package getPackage()获取该类型所在的包
Class getSuperclass()返回该类型的超类的 Class 实例
Class[] getInterfaces()返回该类型所实现的全部接口的 Class 实例
int getModifiers()返回该类型的所有修饰符,由 public、protected、private、final、staic、abstract 等对应的 int 常量组成,返回的整数应使用 Modifier 工具类来解码,才可以判断修饰符的构成
Class[] getDeclaredClasses()返回该类型中包含的全部内部类的 Class 实例
Class getDeclaringClass()返回该类型所在的外部类的 Class 实例
  • 演示案例
public class Xz01 {public static void main(String[] args) throws ClassNotFoundException {Class<Student> c1 = Student.class;Class<?> c2 = new Student().getClass();Class<?> c3 = Class.forName("xuanzi.Student");System.out.println(c1.hashCode());System.out.println(c2.hashCode());System.out.println(c3.hashCode());System.out.println(c1 == c2);
//        hashCode 编码以及 内存地址一致表示同一个 Class 对象System.out.println("获取全类名(包含包路径):" + c1.getName());System.out.println("获取类名(仅类名称):" + c1.getSimpleName());System.out.println("获取包名(仅包名):" + c1.getPackage().getName());System.out.println("获取类加载器:" + c1.getClassLoader());System.out.println("获取父类路径:" + c1.getSuperclass().getName());System.out.println("获取类访问修饰符:" + c1.getModifiers());System.out.println("表示 PUBLIC:" + Modifier.PUBLIC);}
}
//    1324119927
//    1324119927
//    1324119927
//    true
//    获取全类名(包含包路径):xuanzi.Student
//    获取类名(仅类名称):Student
//    获取包名(仅包名):xuanzi
//    获取类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
//    获取父类路径:java.lang.Object
//    获取类访问修饰符:1
//    表示 PUBLIC:1

1.4.2 获取构造方法信息

方法说明
Constructor getConstructor(Class… params)返回该类型指定参数列表的 public 构造方法,构造方法的参数列表与 params 所指定的类型列表所匹配
Constructor[] getConstructors()返回该类型的所有 public 构造方法
Constructor getDeclaredConstructor(Class… params)返回该类型的指定参数列表的构造方法,访问级别不限
Constructor[] getDeclaredConstructors()返回该类型的所有构造方法,访问级别不限
  • 演示案例
public class Xz02 {public static void main(String[] args) throws NoSuchMethodException {Class<Student> c1 = Student.class;Constructor<Student> constructor = c1.getConstructor();Constructor<?>[] constructors = c1.getConstructors();Constructor<Student> declaredConstructor = c1.getDeclaredConstructor();Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();Constructor<?> declaredConstructors1 = c1.getDeclaredConstructor(String.class);System.out.println(constructor);System.out.println(Arrays.toString(constructors));System.out.println(declaredConstructor);System.out.println(Arrays.toString(declaredConstructors));System.out.println(declaredConstructors1);System.out.println("================================");for (Constructor<?> cc : declaredConstructors) {int modifier = cc.getModifiers();String xiu = "";if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {xiu = "PUBLIC";} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {xiu = "PROTECTED";} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {xiu = "FINAL";} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {xiu = "ABSTRACT";} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {xiu = "PRIVATE";} else {xiu = "未知";}System.out.println(xiu);}System.out.println("================================");Class<?>[] parameterTypes = declaredConstructors1.getParameterTypes();if (parameterTypes.length == 0) {System.out.println("无参");} else {for (int i = parameterTypes.length - 1; i >= 0; i--) {System.out.println(parameterTypes[i].getSimpleName());}}System.out.println("================================");}
}
//    public xuanzi.Student()
//    [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student()]
//    public xuanzi.Student()
//    [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student(), protected xuanzi.Student(java.lang.String), private xuanzi.Student(java.lang.String,int)]
//    protected xuanzi.Student(java.lang.String)
//    ================================
//    PUBLIC
//    PUBLIC
//    PROTECTED
//    PRIVATE
//    ================================
//    String
//    ================================

1.4.3 获取属性信息

方法说明
Field getField(String name)返回该类型中指定名称的 public 属性,name 参数用于指定属性名称
Field[] getFields()返回该类型中所有 public 属性
Field getDeclaredField(String name)返回该类型中指定名称的属性,与属性的访问级别无关
Field[] getDeclaredFields()返回该类型中的全部属性,与属性的访问级别无关
  • 演示案例
public class Xz03 {public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {Class<Student> c1 = Student.class;Field[] fields = c1.getFields();Field name = c1.getField("name");Field declaredName = c1.getDeclaredField("name");Field[] declaredFields = c1.getDeclaredFields();System.out.println(Arrays.toString(fields));System.out.println(name);System.out.println(declaredName);System.out.println(Arrays.toString(declaredFields));System.out.println("================================");for (Field df : declaredFields) {int modifier = df.getModifiers();String xiu = "";if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {xiu = "PUBLIC";} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {xiu = "PROTECTED";} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {xiu = "FINAL";} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {xiu = "ABSTRACT";} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {xiu = "PRIVATE";} else {xiu = "未知";}System.out.println(xiu);}System.out.println("================================");for (Field declaredField : declaredFields) {System.out.print(declaredField.getModifiers() + " - ");System.out.print(declaredField.getName() + " - ");System.out.print(declaredField.getType() + " - ");System.out.println();}System.out.println("================================");}
}
//    [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age]
//    public java.lang.String xuanzi.Student.name
//    public java.lang.String xuanzi.Student.name
//    [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age, private char xuanzi.Student.gender]
//    ================================
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    ================================
//    1 - name - class java.lang.String -
//    1 - age - int -
//    2 - gender - char -
//    ================================

1.4.4 获取方法信息

方法说明
Method getMethod(String name, Class… params)返回该实例中指定的 public 方法,name 参数用于指定方法名称,params 参数指定参数列表
Method[] getMethods()返回该实例中所有 public 方法
Method getDeclaredMethod(String name, Class… params)返回该实例中指定的方法,与方法的访问级别无关
Method[] getDeclaredMethods()返回该实例中的全部方法,与方法的访问级别无关
  • 演示案例
public class Xz04 {public static void main(String[] args) throws NoSuchMethodException {Class<Student> c1 = Student.class;Method[] methods = c1.getMethods();Method getStudent = c1.getMethod("setName", String.class);Method[] declaredMethods = c1.getDeclaredMethods();Method declaredMethod = c1.getDeclaredMethod("getGender");System.out.println(getStudent);System.out.println(Arrays.toString(methods));System.out.println(Arrays.toString(declaredMethods));System.out.println(declaredMethod);System.out.println("================================");for (Method dm : declaredMethods) {int modifier = dm.getModifiers();String xiu = "";if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {xiu = "PUBLIC";} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {xiu = "PROTECTED";} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {xiu = "FINAL";} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {xiu = "ABSTRACT";} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {xiu = "PRIVATE";} else {xiu = "未知";}System.out.println(xiu);}System.out.println("================================");for (Method declaredField : declaredMethods) {System.out.print((declaredField.getModifiers() == Modifier.PUBLIC ? "PUBLIC" : "PRIVATE") + " - ");System.out.print(declaredField.getName() + " - ");System.out.print(declaredField.getReturnType().getSimpleName() + " - ");System.out.print(Arrays.toString(declaredField.getParameterTypes()) + " - ");System.out.print(Arrays.toString(declaredField.getExceptionTypes()) + " - ");System.out.println();}System.out.println("================================");}
}
//    public void xuanzi.Student.setName(java.lang.String)
//    [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), public void xuanzi.Student.setGender(char), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
//    [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), private char xuanzi.Student.getGender(), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), private java.lang.String xuanzi.Student.show(java.lang.String,int,char), public void xuanzi.Student.setGender(char)]
//    private char xuanzi.Student.getGender()
//    ================================
//    PUBLIC
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    PUBLIC
//    ================================
//    PUBLIC - getName - String - [] - [] -
//    PUBLIC - toString - String - [] - [class java.lang.IllegalArgumentException, class java.lang.ArithmeticException] -
//    PUBLIC - setName - void - [class java.lang.String] - [] -
//    PRIVATE - getGender - char - [] - [] -
//    PUBLIC - getAge - int - [] - [] -
//    PUBLIC - setAge - void - [int] - [] -
//    PRIVATE - show - String - [class java.lang.String, int, char] - [] -
//    PUBLIC - setGender - void - [char] - [] -
//    ================================

1.5 反射实例化对象

1.5.1 通过反射实现类的实例化

  • java.lang.Class
Student student = Student.class.newInstance();
//        通过 class 获取对象		
  • java.lang.reflect.Constructor
Student student = Student.class.getConstructor().newInstance();
//        通过构造获取对象
  • 演示案例
public class Xz05 {public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {Student student = new Student();
//        直接 new 对象Student student1 = Student.class.newInstance();
//        通过 class 获取对象Student student2 = Student.class.getConstructor().newInstance();
//        通过构造获取对象Constructor<Student> studentConstructor = Student.class.getConstructor(String.class, char.class);studentConstructor.setAccessible(true);
//        通过有参构造获取对象Student student3 = studentConstructor.newInstance("XuanZi", '男');Constructor<Student> studentConstructor1 = Student.class.getDeclaredConstructor(String.class, int.class);studentConstructor1.setAccessible(true);
//      可设置私有构造函数Student student4 = studentConstructor1.newInstance("XuanZi", 12);System.out.println(student);System.out.println(student1);System.out.println(student2);System.out.println(student3);System.out.println(student4);}
}
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='XuanZi', age=0, gender=男}
//    xuanzi.Student{name='XuanZi', age=12, gender= }

1.5.2 通过反射访问实例的字段

java.lang.reflect.Field

方法说明
xxx getXxx(Object obj)xxx 表示8种基本数据类型之一,若 Field 实例表示的是一个静态属性,则 obj 可以设置为 null
Object get(Object obj)以 Object 类型返回 obj 中相关属性的值
void setXxx(Object obj, xxx val)将 obj 中相关属性的值设置为 val。xxx 为8种基本数据类型之一
void set(Object obj, Object val)将 obj 中相关属性的值设置为 val
void setAccessible(boolean flag)对相关属性设置访问权限。设置为 true 可以禁止 Java 语言访问检查
  • 演示案例
public class Xz06 {public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {Class<Student> studentClass = Student.class;Student student = studentClass.newInstance();Field name = studentClass.getField("name");System.out.println(name.get(student));name.set(student, "玄子");System.out.println(name.get(student));}
}
//    null
//    玄子

1.5.3 通过反射调用实例的方法

java.lang.reflect.Method

public  Object  invoke( Object obj, Object...  args )
  • Object:返回值
  • Object obj:执行该方法的对象
  • Object… args:执行该方法时传入的参数
  • 演示案例
public class Xz07 {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {Class<Student> studentClass = Student.class;Student student = studentClass.newInstance();Method name = studentClass.getMethod("setName", String.class);name.invoke(student, "张三");System.out.println(student);}
}
//    xuanzi.Student{name='张三', age=0, gender= }

1.6 反射的优缺点

1.6.1 优点

  • 允许程序创建和控制任何类的对象,无需提前硬编码目标类
  • 提高了 Java 程序的灵活性和扩展性,降低了耦合性,提高自适应能力
  • 反射的应用领域:开源框架,如 MyBatis、Spring 等

1.6.2 缺点

  • 性能问题:反射机制主要应用在对灵活性和扩展性要求很高的系统框架上
  • 代码维护问题:反射会模糊程序内部逻辑,可读性较差,且反射可能会破坏封装

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/98450.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

svn checkout 报 ‘svn: E000061: 执行上下文错误: Connection refused‘

问题 svn: E170013svn: E000061 ➜ svn svn checkout https://xxx.xxx.xxx.xxx:9443/svn/project-xxx/ svn: E170013: Unable to connect to a repository at URL https://xxx.xxx.xxx.xxx:9443/svn/project-xxx svn: E000061: 执行上下文错误: Connection refused链接在浏览…

说说Lambda架构

分析&回答 Lambda架构是由Storm的作者Nathan Marz提出的一个实时大数据处理框架。Marz在Twitter工作期间开发了著名的实时大数据处理框架Storm&#xff0c;Lambda架构是其根据多年进行分布式大数据系统的经验总结提炼而成。Lambda架构的目标是设计出一个能满足实时大数据系…

大模型优化:RAG还是微调?

引言 随着人们对大型语言模型 (LLM) 的兴趣激增&#xff0c;许多开发人员和组织正忙于利用其能力构建应用程序。然而&#xff0c;当开箱即用的预训练LLM没有按预期或希望执行时&#xff0c;如何提高LLM申请的性能的问题。最终我们会问自己&#xff1a;我们应该使用检索增强生成…

微服务容错 Resilience4j 接口服务-容错原理

微服务容错 Resilience4j 容错原理 4.1 微服务容错简介 在⾼并发访问下&#xff0c;⽐如天猫双11&#xff0c;流量持续不断的涌⼊&#xff0c;服务之间的相互调⽤频率突然增加&#xff0c;引发系统负载过⾼&#xff0c;这时系统所依赖的服务的稳定性对系统的影响⾮常⼤&#…

大厂面试 | 百度一面,顶不住

题目来源&#xff1a;https://www.nowcoder.com/feed/main/detail/d39aabc0debd4dba810b4b9671d54348 前文 本期是【捞捞面经】系列文章的第 2 期&#xff0c;持续更新中…。&#xff08;更多与往期下方仓库直达&#xff09; 《捞捞面经》系列正式开始连载啦&#xff0c;据说看…

Elasticsearch 对比传统数据库:深入挖掘 Elasticsearch 的优势

当你为项目选择数据库或搜索引擎时&#xff0c;了解每个选项的细微差别至关重要。 今天&#xff0c;我们将深入探讨 Elasticsearch 的优势&#xff0c;并探讨它与传统 SQL 和 NoSQL 数据库的比较。 1. Elasticsearch简介 Elasticsearch 以强大的 Apache Lucene 库为基础&#…

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 目录 Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 一、简单介绍 二、OKHttp 4.xx 的 SDK 封装 aar 给 Unity 的使用注意 三、附录 OKHttp 的…

在线客服如何与客户进行有效沟通?

在今天的“互联网”时代&#xff0c;越来越多的服务都开始向线上转移&#xff0c;其中最受欢迎的莫过于在线客服。在线客服不仅可以提供7x24小时的在线咨询服务&#xff0c;还可以提高企业的服务效率和满意度。然而&#xff0c;有时候在线客服与客户之间的沟通效果却不太令人满…

el-table 垂直表头

效果如下&#xff1a; 代码如下&#xff1a; <template><div class"vertical_head"><el-table style"width: 100%" :data"getTblData" :show-header"false"><el-table-columnv-for"(item, index) in getHe…

外包干了2个月,技术退步明显了...

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年8月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

神仙级python入门教程(非常详细),从0到精通,从看这篇开始!

毫无疑问&#xff0c;Python 是当下最火的编程语言之一。对于许多未曾涉足计算机编程的领域「小白」来说&#xff0c;深入地掌握 Python 看似是一件十分困难的事。其实&#xff0c;只要掌握了科学的学习方法并制定了合理的学习计划&#xff0c;Python 从 入门到精通只需要一个月…

【计算机网络】 静态库与动态库

文章目录 静态库实践使用方法总结 动态库实践使用方法总结 静态库与动态库的优缺点静态库优点缺点 动态库缺点优点 库有两种&#xff1a;静态库&#xff08;.a、.lib&#xff09;和动态库&#xff08;.so、.dll&#xff09;。所谓静态、动态是指链接。静态库是将整个库文件都拷…