Java反射
来源:互联网 发布:北京网络预约挂号平台 编辑:程序博客网 时间:2024/05/25 16:39
一、基本介绍
Java反射机制可以的运行期(Runtime)获得任何一个类的字节码。包括接口、变量、方法等信息。还可以让我们在运行期实例化对象,通过调用get/set方法获取变量的值。
1. Java反射包名为:java.lang.reflect 。以下为常用的接口和类
接口
- Type 是 Java 编程语言中所有类型的公共高级接口。
- ParameterizedType 表示参数化类型,即形参类型,如 Collection。
类
- Field 提供有关类或接口的单个字段(变量)的信息,以及对它的动态访问权限。
- Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
- Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
- Modifier 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。
2. 反射体系中还有一个重要的类java.lang.Class,它是反射的起点,通过Class对象,才能获取反射体系中其它对象,一共有三种实例化方法,下面API有介绍。
解释:Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
二、常用API介绍
以Father和Son两个类为测试对象,类和测试代码在:
(https://github.com/shengpli/learnExample/tree/master/src/main/java/reflection)
1. 获取类的class对象
Class<Father> fatherClass ;Class<Son> sonClass;//方式一fatherClass = Father.class;sonClass = Son.class;//方式二Father father = new Father();Son son = new Son();fatherClass = (Class<Father>) father.getClass();sonClass = (Class<Son>) son.getClass();//方式三fatherClass = (Class<Father>) Class.forName("reflection.Father");sonClass = (Class<Son>) Class.forName("reflection.Son");
2. 获取变量
- 获取公有(public)变量
//getFields只能获取公有的变量 Field[] fields = fatherClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); }
- 获取所有变量,并访问私有变量
//getDeclaredFields能获取所有变量 Field[] declaredFields = fatherClass.getDeclaredFields(); Father father = new Father(); father.setAge("33").setName("zhangsan").setSex("man"); for (Field declaredField : declaredFields) { //通过调用 setAccessible(true)方法会关闭指定类 Field 实例的反射访问检查,这行代码执行之后不论是私有的、 // 受保护的以及包访问的作用域,你都可以在任何地方访问,即使你不在他的访问权限作用域之内。 declaredField.setAccessible(true); //获取变量名称 System.out.println(declaredField.getName()); //获取变量值 System.out.println(declaredField.get(father)); }
3.获取构造方法,并利用构造方法类实例化对象
//获取公有的(Public)构造方法类 Constructor<?>[] constructors = sonClass.getConstructors(); //获取所有构造方法类 Constructor<?>[] declaredConstructors = sonClass.getDeclaredConstructors(); //如果你知道你要访问的构造方法的方法参数类型,你可以用下面的方法获取指定的构造方法类 Constructor<Son> sonConstructor = sonClass.getConstructor(new Class[]{String.class, String.class, String.class}); //利用Constructor.newInstance实例化一个类 Son son = sonConstructor.newInstance("zhangsan", "man", "12"); System.out.println(son.toString()); //获取构造方法的参数类 Class<?>[] parameterTypes = sonConstructor.getParameterTypes(); for (Class<?> parameterType : parameterTypes) { String name = parameterType.getName(); System.out.println(name); }
4.获取所有public方法;invoke调用方法
//获取公有的(public)方法类。 Method[] methods = fatherClass.getMethods(); for (Method method : methods) { System.out.println(method.getName()); } //通过方法名和参数类型来获取指定的方法。如果你想要获取的方法没有参数,那么在调用 getMethod()方法时第二个参数传入 null 即可 Method singMethod = fatherClass.getMethod("sing", String.class); System.out.println(singMethod.getName()); //调用方法 Object o = singMethod.invoke(new Father(), "小苹果"); System.out.println(o.toString());
5.获取所有方法
//获取所有方法 Method[] declaredMethods = fatherClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod.getName()); } //获取指定方法 Method play = fatherClass.getDeclaredMethod("play", String.class); //通过调用 setAccessible()方法会关闭指定类的 Method 实例的反射访问检查, // 这行代码执行之后不论是私有的、受保护的以及包访问的作用域,你都可以在任何地方访问,即使你不在他的访问权限作用域之内。 play.setAccessible(true); Father father = new Father(); //调用方法 Object o = play.invoke(father, "ping pong"); System.out.println(o.toString());
6.获取一个类的修饰符(public、private等)
int modifiers = fatherClass.getModifiers(); System.out.println(Modifier.isPublic(modifiers));
7.获取类的名称
//全限定类名(包含包名) String name = fatherClass.getName(); System.out.println(name); //类的名字(不包含包名) String simpleName = fatherClass.getSimpleName(); System.out.println(simpleName);
8.获取父类
Class<? super Son> superclass = sonClass.getSuperclass(); String superclassName = superclass.getName(); System.out.println(superclassName);
9.获取实现接口
Class<?>[] interfaces = sonClass.getInterfaces(); for (Class<?> anInterface : interfaces) { String name = anInterface.getName(); System.out.println(name); }
10.处理泛型变量
Method eatMethod = fatherClass.getMethod("eat", Map.class); //获取方法返回参数泛型类型 Type returnType = eatMethod.getGenericReturnType(); if(returnType instanceof ParameterizedType){ ParameterizedType type = (ParameterizedType) returnType; Type[] returnArguments = type.getActualTypeArguments(); for(Type returnArgument : returnArguments){ Class returnArgClass = (Class) returnArgument; System.out.println("returnArgClass = " + returnArgClass); } } //获取方法形参泛型类型 Type[] genericParameterTypes = eatMethod.getGenericParameterTypes(); for(Type genericParameterType : genericParameterTypes){ if(genericParameterType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericParameterType; Type[] parameterArgTypes = aType.getActualTypeArguments(); for(Type parameterArgType : parameterArgTypes){ Class parameterArgClass = (Class) parameterArgType; System.out.println("parameterArgClass = " + parameterArgClass); } } } //获取变量泛型类型 Field field = fatherClass.getField("list"); Type genericType = field.getGenericType(); if(genericType instanceof ParameterizedType){ ParameterizedType fieldType = (ParameterizedType) genericType; Type[] fieldTypeActualTypeArguments = fieldType.getActualTypeArguments(); for(Type type : fieldTypeActualTypeArguments){ Class fieldArgumentsClass = (Class) type; System.out.println("fieldArgumentsClass = " + fieldArgumentsClass); } }
- 【反射】JAVA反射机制
- JAVA 反射
- java 反射
- Java反射
- java反射
- java反射
- JAVA反射
- java 反射
- Java 反射
- java 反射
- Java反射
- java反射
- JAVA 反射
- java 反射
- Java反射
- java反射
- java 反射
- java 反射
- java内部类
- TCP三次握手与四次挥手的过程以及原因
- JDBC初级 上
- [深度学习框架] Keras上使用CNN进行mnist分类
- git忽略本地的已经push过的提交
- Java反射
- 【USACO】2004 Open MooFest 奶牛集会
- 解决安装CentOS7后发现yum无法使用
- 无人驾驶面临的伦理问题
- 11月英语总结
- 好好写
- [深度学习框架] Keras上使用RNN进行mnist分类
- Python 3 多线程下载百度图片搜索结果
- 配置