java 反射机制
积少成多 ---- 仅以此致敬和我一样在慢慢前进的人儿
前提知识储备
1、JVM在加载一个类之后,会在内存空间里面生成与这个类对应的class对象(java.lang.Class)
2、在装载类的时候,加入方法区中的所有信息,最后都会形成Class类的实例,代表这个被装载的类。方法区中的所有的信息,都是可以通过这个Class类对象反射得到。
3、反射其实是获取类的字节码文件, 也就是.class 文件
4、依据获取到class对象可以反射到类
个人理解: 这部分应该介绍class 类 , java类, .class文件之间的关系, 但本人能力不够,待以后补充
相关内容:https://www.cnblogs.com/whoislcj/p/6038511.html
https://baijiahao.baidu.com/s?id=1619748187138646880&wfr=spider&for=pc
https://www.cnblogs.com/wglIT/p/7590468.html
问题一: 什么是Java的反射机制
百度结果: JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java 语言的 反射机制。
个人理解:在编译的过程中,不是确定的创建一个类或者得到类的信息,而是开发人员告诉JVM类的名字(全限定名,如com.qf.controller,这是其中一种方法),然后JVM去解释这些,帮你去找这个类的构造函数,属性, 方法等信息
问题二: 为什么要使用Java反射机制
查询资料:
静态编译:在编译时确定类型,绑定对象,即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多 态的应用,有以降低类之间的藕合性。 一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活 性,特别是在J2EE的开发中 它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编 译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如 这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能 的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。 它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它 满足我们的要求。这类操作总是慢于只直接执行相同的操作。
个人理解:使用java反射机制,在于可以动态创建的过程,具有较大灵活性
问题三:java如何获取每个类对应的class类
获取class类总共有三种方法:
1、通过类的继承父类Object的静态方法getClass()
//第一种方式 通过对象getClass方法
Person person = new Person(); Class<?> class1 = person.getClass();
//第二种方式 通过类的class属性(父类的静态属性) class1 = Person.class;
//第三种方式 通过Class类的静态方法——forName()来实现
try {
class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();}
class.forName("xxxx") 获取xxx对应的class类,并初始化该类(初始化知识在jvm加载了这个类,并不是在创建了类的实例对象)
上面的三种方法,推荐使用第三种,因为前两种方法是已经获得了类,在通过类来获取对应的class失去了动态性
问题四:如何通过class类获取类的详细信息
Field[] allFields = class1.getDeclaredFields();//获取class对象的所有属性 Field[] publicFields = class1.getFields();//获取class对象的public属性 try { Field ageField = class1.getDeclaredField("age");//获取class指定属性 Field desField = class1.getField("des");//获取class指定的public属性 } catch (NoSuchFieldException e) { e.printStackTrace(); } Method[] methods = class1.getDeclaredMethods();//获取class对象的所有声明方法 Method[] allMethods = class1.getMethods();//获取class对象的所有方法 包括父类的方法 Class parentClass = class1.getSuperclass();//获取class对象的父类 Class<?>[] interfaceClasses = class1.getInterfaces();//获取class对象的所有接口 Constructor<?>[] allConstructors = class1.getDeclaredConstructors();//获取class对象的所有声明构造函数 Constructor<?>[] publicConstructors = class1.getConstructors();//获取class对象public构造函数 try { Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});//获取指定声明构造函数 Constructor publicConstructor = class1.getConstructor(new Class[]{});//获取指定声明的public构造函数 } catch (NoSuchMethodException e) { e.printStackTrace(); } Annotation[] annotations = class1.getAnnotations();//获取class对象的所有注解 Annotation annotation = class1.getAnnotation(Deprecated.class);//获取class对象指定注解 Type genericSuperclass = class1.getGenericSuperclass();//获取class对象的直接超类的 Type Type[] interfaceTypes = class1.getGenericInterfaces();//获取class对象的所有接口的type集合
通过上面的方法可以获取到类的所有详细属性
总结
总的来说,java反射机制是一个很好用的东西,用它可以解决很多死的东西,因为反射机制的灵活行很大,有了他,我们就不要花太多的时间来写操做数据库的代码了,而是方法更多的时间在项目的逻辑功能上,这个可以很大的减少开发时间,而且代码的可读性好。先在的很多开源框架都是才用的反射机制,它只要配置文件,然后按规则来调用他的方法就可以了。