java_反射
2019-04-28 08:23:29来源:博客园 阅读 ()
反射:reflect 成员属性:Field 成员方法:Method 构造方法:Constructor 类:Class
引用,援引:invoke 新实例:newInstance Declared:公开
什么是反射?
反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员
是一种通过class文件对类中所有成员属性,构造方法,成员方法进行操作的方式,无论是什么权限都可以进行操作
什么是Class对象?
学习反射主要是操作Class对象,那么什么是Class对象?
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
class文件和Class是两个概念
也就是说,Class也是java语言中的一个类,程序运行时,会将class文件加载到内存并对该类进行解剖,解剖类时会获得很多的数据,有成员变量数据,成员方法数据,构造方法数据等,JVM为了方便管理这些类的数据,内部会为每一个加载到内存的class文件创建一个Class对象,这个Class对象目的就是用来封装解剖得到的所有该类的数据
操作Class对象即可获取对应类的数据
创建对象的五种方式:
- 直接new对象
String str=new String(“张三”);
- 如果类中有无参构造方法,可以使用该类对应的Class文件直接创建对象(反射)
Student s=Student.class.newInstance();
- 通过类的Class对象获取该类的构造方法,通过构造方法创建对象(反射)
Class s1=Student.class;
Constructor c1=c1.getConstructor();
Student s2=c1.newInstance();
- 通过反序列化获取对象
- 通过Clone….获取对象(了解)
反射有什么用,有什么应用的地方?
- 一种新的创建对象,操作对象的方式
- 可以降低程序的耦合度,降低程序的维护难度
举例说明:
通过反射比较常用的获取类对象的方式:
Class class=Class.forName(“包名.类名”);
通过类的全限命名(字符串类型)即可创建对象,可以将该字符串以键值对的形式存储到properties文件中,
如果类名改变,只需要修改properties配置文件即可
而通过new出来的对象,如果类名发生改变,则需要修改代码
- ssh(Spring,Struts,Hibernate)框架底层就使用了大量的反射
反射怎么使用?
先总结一下,通过反射可以获取类的构造方法(Constructor),成员属性(Field),成员方法(Method),针对操作公有数据和操作所有权限数据分开来说
操作公有数据:
获取构造方法:如果构造函数有参数在参数列表加上相应参数类型的class属性即可
Constructor getConstructor()
Constructor[] getConstructors()
获取成员属性:需要传入属性名称
Field getField(String name);
Field[] getFields();
获取成员方法:(通过方法名称和参数才能唯一标识一个方法,所以需要传入方法名称和参数)
Method getMethod(String methodName,参数…)
Method[] getMethods()
操作所有权限的数据
在操作公有数据基础上,get后面加上Declared,如果操作构造方法或者成员属性或者成员方法,先用方法对象或者属性对象调用setAccessible并且传入true即可
代码详解:
package com.ahd.lianxi; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo01 { public static void main(String[] args) throws Exception { //练习反射 /* * 获取Class对象的三种方式 * 方式一:通过对象调用getClass方法获取 * * 方式二:通过类名的class属相获取 * * 方式三:通过类的权限命名加载Class文件,需要抛出异常(这种方法比较常用) * */ Student s=new Student("zhangsan"); Class<? extends Student> c1 = s.getClass(); Class<Student> c2 = Student.class; Class.forName("com.ahd.lianxi.Student"); /* * 获取Class对象,可以通过该对象获取该对象相应的构造方法,成员属性 * ,成员方法,进而进行操作 * 首先说操作构造方法,创建对象 * Constructor<? extends Student> constructorC1 = c1.getConstructor(); * 该构造方法获取公有的构造方法,传入相应的参数表示获取对应的构造方法, * Constructor<? extends Student> declaredConstructorC1 = c1.getDeclaredConstructor(); * 该构造方法获取所有权限的构造方法,传入相应的参数表示获取对应的构造方法,比较常用 * Constructor<?>[] constructors = c1.getConstructors(); * 该构造方法获取所有公有的构造方法,比较常用 * Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors(); * 该构造方法获取所有权限的构造方法, * * 如果要通过无参构造方法创建对象,可以直接使用Class对象的newInstance方法获取相应对象 * Student student1 = c1.newInstance(); * */ Constructor<? extends Student> constructorC1 = c1.getConstructor(); Constructor<? extends Student> constructorC2 = c1.getConstructor(String.class); Constructor<? extends Student> declaredConstructorC1 = c1.getDeclaredConstructor(); Constructor<?>[] constructors = c1.getConstructors(); Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors(); //通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下 //declaredConstructorC1.setAccessible(true); declaredConstructorC1.setAccessible(true); //通过迭代器可以遍历所有构造方法,进行相应操作 //略... //使用构造方法创建对象 Student student = constructorC1.newInstance(); Student student2 = constructorC2.newInstance("赵四"); /* * 通过Class对象获取成员属性 * Field field1 = c1.getField("username"); * 获取公有的指定属性名称的属性对象 * Field field2 = c1.getDeclaredField("username"); * 获取所有权限的指定属性名称的属性对象 * Field[] fields = c1.getFields(); * 获取公有的所有属性对象 * Field[] declaredFields = c1.getDeclaredFields(); * 获取所有权限的所有属性对象 * */ Field field1 = c1.getField("username"); Field field2 = c1.getDeclaredField("username"); //通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下 //field2.setAccessible(true); field2.setAccessible(true); /* * 对属性进行操作 * get方法获取属性的值: Object get(Object obj) * 返回指定对象上此 Field 表示的字段的值。 * set方法为属性赋值:void set(Object obj, Object value) * 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 * 个人理解:obj即该成员属性所属于的对象,value为为该属性赋的值 * */ field1.set(student,"lisi"); System.out.println(field1.get(student)); Field[] fields = c1.getFields(); Field[] declaredFields = c1.getDeclaredFields(); //通过迭代器可以遍历所有属性,进行相应操作 //略... /* * 通过Class对象获取成员方法,获取成员方法需要传入方法名称和参数类型(类型是对应的class文件) * ,方法获取后可以指定对象调用成员方法 * ,调用成员方法需要指定对象和参数列表(可变参数) * public Method getMethod(String name, * Class<?>... parameterTypes) * 获取公有的成员方法 * Method declaredMethod = c1.getDeclaredMethod("getUsername"); * 获取所有权限的一个成员方法 * Method[] methods = c1.getMethods(); * 获取所有公有的成员方法 * Method[] declaredMethods = c1.getDeclaredMethods(); * 获取所有具有所有权限的成员方法 * * * */ Method method = c1.getMethod("getUsername");//调用无参方法,参数可以不写 Method declaredMethod = c1.getDeclaredMethod("getUsername"); //通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下 //declaredMethod.setAccessible(true); declaredMethod.setAccessible(true); Method[] methods = c1.getMethods(); Method[] declaredMethods = c1.getDeclaredMethods(); System.out.println("##########################"); //方法调用 method.invoke(student); System.out.println(method.invoke(student)); } }
我有一句话想要对你说
地基越牢固,楼才能建的更高
笔者原创,欢迎大佬指出错误
原文链接:https://www.cnblogs.com/aihuadung/p/10783492.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash