当前位置: 首页 > news >正文

反射---Java

目录

反射是什么

作用一:检查类的结构:通过反射可以看到,某个类的内部字段(field)、方法(method)、构造方法(constructor)

作用二:运行时分析对象:可以查看在编译时还不知道的值,在debug时可以使用到

作用三:调用任意的方法和构造器:类似的实现了C/C++的指针的功能

作用四:编写泛型数组代码

在Spring设计中用到反射

在mybatis中使用到的反射


反射是什么

Java核心技术卷Ⅰ:能够分析类能力的程序称之为反射,个人理解包括检查类的结构覆盖类的字段值或方法

作用:在运行时分析类的能力、在运行时检查对象、实现泛型数组操作代码、利用method对象

理解class类:Java运行时系统始终为所有的对象维护一个运行时类型标识,这个信息会跟踪每个对象所属的类,虚拟机利用这个信息选择要执行的正确方法

作用一:检查类的结构:通过反射可以看到,某个类的内部字段(field)、方法(method)、构造方法(constructor)
此处使用的方法解释
getField()返回值(class数组),作用(返回类的及其超类的公共字段)
getDeclaredFields()返回值(class数组),作用(返回这个类的全部字段,如果没有或者类描述的是一个基本类型或数组类型,那么其长度为0)
getMethods()返回值(Method数组),作用(返回类的及其超类继承过来的方法)
getDeclaredMethods()返回值(Method数组),作用(返回这个类/接口的全部方法,不包括继承过来的方法)
getConstructor()返回值(Constructor数组),作用(返回这个类的全部公共构造器)
getDeclaredConstructor()返回值(Constructor数组),作用(返回这个类的全部构造器)
getPackageName()返回数组类型,返回元素所属的包
getModifiers()返回值(int) 描述构造器、方法、字段的修饰符
getParameterTypes()返回值(class数组)作用(方法/构造器参数的类型)
getReturnType()返回值(class对象)作用(方法的返回值类型)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
​
/*** @author Rui* @description 反射检查某个类的结构* @create 2024/8/11 0:28*/
public class ReflectionTest {private static final int PI = 3;public static void main(String[] args) throws ReflectiveOperationException {String name;name = "java.lang.Double";Class clazz = Class.forName(name);//构造器Constructor[] constructors = clazz.getConstructors();for (Constructor constructor : constructors) {//打印构造器方法String modifiers = Modifier.toString(constructor.getModifiers());System.out.print("\n构造器名字:" + modifiers + " " + name + "  参数 (");//打印参数Class[] parameterTypes = constructor.getParameterTypes();for (Class parameterType : parameterTypes) {System.out.print(parameterType.getName() + ",");}System.out.print(")");}System.out.println("\n----------------------");
​//方法Method[] methods = clazz.getDeclaredMethods();System.out.println("方法:");for (Method method : methods) {//返回值类型Class retType = method.getReturnType();//方法的权限String modifiers = Modifier.toString(method.getModifiers());//打印参数Class[] parameterTypes = method.getParameterTypes();System.out.print(modifiers + " " + retType + " " + method.getName()+"(");for (Class parameterType : parameterTypes) {System.out.print(parameterType.getName() + ",");}System.out.println(")");}System.out.println("----------------------");
​//字段Field[] fields = clazz.getDeclaredFields();System.out.println("字段:");for (Field field : fields) {//字段的权限String modifiers = Modifier.toString(field.getModifiers());//字段的类型Class type = field.getType();//字段的名字String name1 = field.getName();System.out.println(modifiers + " " + type.getName() + " " + name1);}
​}
}
构造器名字:public java.lang.Double  参数 (double,)
构造器名字:public java.lang.Double  参数 (java.lang.String,)
----------------------
方法:
public boolean equals(java.lang.Object,)
public static class java.lang.String toString(double,)
public class java.lang.String toString()
public int hashCode()
public static int hashCode(double,)
public static double min(double,double,)
public static double max(double,double,)
public static native long doubleToRawLongBits(double,)
public static long doubleToLongBits(double,)
public static native double longBitsToDouble(long,)
public volatile int compareTo(java.lang.Object,)
public int compareTo(java.lang.Double,)
public byte byteValue()
public short shortValue()
public int intValue()
public long longValue()
public float floatValue()
public double doubleValue()
public static class java.lang.Double valueOf(java.lang.String,)
public static class java.lang.Double valueOf(double,)
public static class java.lang.String toHexString(double,)
public static int compare(double,double,)
public static boolean isNaN(double,)
public boolean isNaN()
public static boolean isFinite(double,)
public static boolean isInfinite(double,)
public boolean isInfinite()
public static double sum(double,double,)
public static double parseDouble(java.lang.String,)
----------------------
字段:
public static final double POSITIVE_INFINITY
public static final double NEGATIVE_INFINITY
public static final double NaN
public static final double MAX_VALUE
public static final double MIN_NORMAL
public static final double MIN_VALUE
public static final int MAX_EXPONENT
public static final int MIN_EXPONENT
public static final int SIZE
public static final int BYTES
public static final java.lang.Class TYPE
private final double value
private static final long serialVersionUID
​
进程已结束,退出代码0
作用二:运行时分析对象:可以查看在编译时还不知道的值,在debug时可以使用到
代码解释
Object value = f.get (obj)obj是个类,f66是类里面的某个字段名,通过该方法可以返回该字段值但是是一个对象的形式
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
​
/*** @author Rui* @description 复写通用的ToString()方法* @create 2024/8/11 16:07*/
public class ObjectAnalyzer {private ArrayList<Object> visvit = new ArrayList<>();
​public String toString(Object obj) throws ReflectiveOperationException{if(obj == null) return "null";if(visvit.contains(obj)) return "...";visvit.add(obj);Class cl = obj.getClass();if(cl == String.class) return (String)obj;if(cl.isArray()){String r = cl.getComponentType() + "[]{";for(int i = 0; i < Array.getLength(obj); i++){if(i > 0) r += ",";Object val = Array.get(obj,i);if(cl.getComponentType().isPrimitive()) r += val;else r += toString(val);}return r + "}";}String r = cl.getName();do{r += "[";Field[] fields = cl.getDeclaredFields();AccessibleObject.setAccessible(fields,true);for(Field f : fields){if(!Modifier.isStatic(f.getModifiers())){if(!r.endsWith("[")) r += ",";r += f.getName() + "=";Class  t = f.getType();Object val = f.get(obj);if(t.isPrimitive()) r += val;else r += toString(val);}}r += "]";cl = cl.getSuperclass();}while(cl != null);return r;}
}
​
//测试过程
import java.util.ArrayList;
​
/*** @author Rui* @description 复写的ToString()方法测试* @create 2024/8/11 16:08*/
public class ObjectAnalyzerTest {public static void main(String[] args) throws ReflectiveOperationException{ArrayList<Integer> squares = new ArrayList<Integer>();for (int i = 1; i <= 5; i++) {squares.add(i * i);}System.out.println("squares: " + squares.toString());System.out.println(new ObjectAnalyzer().toString(squares));}
}
squares: [1, 4, 9, 16, 25]
java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][][]
​
进程已结束,退出代码0
作用三:调用任意的方法和构造器:类似的实现了C/C++的指针的功能
import java.lang.reflect.Method;
​
/*** @author Rui* @description 功能上类似实现了C/C++的指针功能* @create 2024/8/11 16:42*/
public class MethodTableTest {public static void main(String[] args) throws ReflectiveOperationException {Method square = MethodTableTest.class.getMethod("square", double.class);Method sqrt = Math.class.getMethod("sqrt", double.class);
​printTable(1, 10, 10, square);printTable(1, 10, 10, sqrt);
​}
​public static double square(double x) {return x * x;}
​public static void printTable(double from, double to, int n, Method f) throws ReflectiveOperationException {System.out.println(f);double dx = (to - from) / (n - 1);for (double x = from; x <= to; x += dx){double y = (Double) f.invoke(null, x);System.out.printf("%10.4f | %10.4f%n", x, y);}}
}
public static double MethodTableTest.square(double)1.0000 |     1.00002.0000 |     4.00003.0000 |     9.00004.0000 |    16.00005.0000 |    25.00006.0000 |    36.00007.0000 |    49.00008.0000 |    64.00009.0000 |    81.000010.0000 |   100.0000
public static double java.lang.Math.sqrt(double)1.0000 |     1.00002.0000 |     1.41423.0000 |     1.73214.0000 |     2.00005.0000 |     2.23616.0000 |     2.44957.0000 |     2.64588.0000 |     2.82849.0000 |     3.000010.0000 |     3.1623
​
进程已结束,退出代码0
作用四:编写泛型数组代码
import java.lang.reflect.Array;
import java.util.Arrays;
​
/*** @author Rui* @description 编写泛型数组代码* @create 2024/8/11 17:39*/
public class CopyOfTest {public static void main(String[] args) {int[] a = {1,2,3};a = (int[]) goodCopyOf(a,10);System.out.println(Arrays.toString(a));
​String[] b = {"Tom","Dick","Harry"};b = (String[]) goodCopyOf(b,10);System.out.println(Arrays.toString(b));
​System.out.println("下面的调用将生成一个异常。");b = (String[]) badCopyOf(b,10);}
​public static Object[] badCopyOf(Object[] a, int newLength) {Object[] newArray = new Object[newLength];System.arraycopy(a,0,newArray,0,Math.min(a.length,newLength));return newArray;}
​public static Object goodCopyOf(Object a, int newLength) {Class cl = a.getClass();if (!cl.isArray()) return null;Class componentType = cl.getComponentType();int length = Array.getLength(a);Object newArray = Array.newInstance(componentType,newLength);System.arraycopy(a,0,newArray,0,Math.min(length,newLength));return newArray;}
}
[1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
[Tom, Dick, Harry, null, null, null, null, null, null, null]
下面的调用将生成一个异常。
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;at CopyOfTest.main(CopyOfTest.java:20)
​
进程已结束,退出代码1
在Spring设计中用到反射

1.1创建Bean实例的时候使用到了反射

       当容器启动时,他会扫描配置文件或者注解来确定那些类需要类实例化,并使用反射调用构造函数

1.2依赖注入时使用了反射

        开发者通过声明式的管理对象之间的依赖关系,Spring使用反射来访问类的信息,包括字段、方法、构造方法,然后哥们个根据信息自动注入所需的依赖

1.3 AOP面向切面编程

        使用动态代理来实现方法的拦截,Spring使用反射动态的创建一个代理对象,该对象会拦截方法调用,并在方法执行前后添加额外的行为

在mybatis中使用到的反射

1.1使用反射完成动态代理

        mybatis使用JDK动态代理来创建Mapper接口的实现类,不需要程序员创建实现类

1.2结果集映射

        mybatis会将查询结果映射到Java对象中

1.3 SQL语句的处理

        mybatis执行SQL时,会根据配置的参数类型,使用反射设置参数

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 达梦数据库的系统视图v$sql_stat
  • Element-UI自学实践
  • 【数据库】MySql深度分页SQL查询优化
  • 前端JS总结(下)之DOM
  • LVS原理——详细介绍
  • dos 常用命令整理
  • 微信小程序的广告变现收益怎么样?
  • 如何高效记录并整理编程学习笔记—笔记工具选择?
  • Windows Server 使用Docke部署挂载问题(安装后无限重启崩溃迁移镜像到D盘打包镜像)
  • SSH、FTP、SFTP相关协议详解
  • Android Framework之Pkms详解
  • fatal: The current branch master has no upstream branch.
  • 【最小生成树】(三) Prim 算法
  • 某通用系统0day审计过程
  • Leetcode - 周赛409
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 4个实用的微服务测试策略
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • EventListener原理
  • exports和module.exports
  • mysql常用命令汇总
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 大主子表关联的性能优化方法
  • 巧用 TypeScript (一)
  • 数据仓库的几种建模方法
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 小程序01:wepy框架整合iview webapp UI
  • 译米田引理
  • 译自由幺半群
  • 责任链模式的两种实现
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (附源码)springboot教学评价 毕业设计 641310
  • (六)激光线扫描-三维重建
  • (十七)Flink 容错机制
  • (转)为C# Windows服务添加安装程序
  • (转载)OpenStack Hacker养成指南
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .Mobi域名介绍
  • .net core 管理用户机密
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .net6 core Worker Service项目,使用Exchange Web Services (EWS) 分页获取电子邮件收件箱列表,邮件信息字段
  • .NET学习教程二——.net基础定义+VS常用设置
  • .Net中ListT 泛型转成DataTable、DataSet
  • ?
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [AIGC] 深入浅出 Python中的`enumerate`函数
  • [C++进阶]map和set的相关题目
  • [CareerCup] 12.3 Test Move Method in a Chess Game 测试象棋游戏中的移动方法
  • [CF482B]Interesting Array
  • [C语言]编译和链接