我是源码,反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射!

Java是一门准动态语言,是因为存在反射机制,如果你不会是不是就等于白学了?看完不会,请评论,我亲自给你解释,嘻嘻!fyz爱图古源码汇
动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如JavaScript便是一个典型的动态语言。
除此之外如Ruby、Python、OC等也都属于动态语言,而C、C++、Java等语言则不属于动态语言。fyz爱图古源码汇
动态类型语言,就是类型的检查是在运行时做的,是不是合法的要到运行时才判断,例如JavaScript就没有编译错误,只有运行错误。fyz爱图古源码汇
静态语言 而静态类型语言的类型判断是在运行前判断(如编译阶段),比如java就是静态类型语言,静态类型语言为了达到多态会采取一些类型鉴别手段,如继承、接口,而动态类型语言却不需要,fyz爱图古源码汇
Java的反射机制被视为Java为准动态语言的主要的一个关键性质,这个机制允许程序在运行时透过反射取得任何一个已知名称的class的内部信息,包括:fyz爱图古源码汇
正在运行中的类的属性信息,正在运行中的类的方法信息,正在运行中的类的构造信息,正在运行中的类的访问修饰符,注解等等。fyz爱图古源码汇
动态语言无时不刻在体现动态性,而静态语言也在通过其他方法来趋近于去弥补静态语言的缺陷。fyz爱图古源码汇
为什么么要使用反射:反射是框架设计的灵魂框架: 半成品软件。可以在框架的基础上进行软件开发,简化编码。学习框架并不需要了解反射,但是要是想自己写一个框架,那么就要对反射机制有很深入的了解。解耦,提高程序的可扩展性在运行时判断任意一个对象所属的类。在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。在运行时调用任意一个对象的方法。什么是反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。fyz爱图古源码汇
简单来说: 将类的各个组成部分封装成其他对象fyz爱图古源码汇
fyz爱图古源码汇
Java代码在计算机中经历的三个阶段fyz爱图古源码汇
Source源代码阶段:.java被编译成.class字节码文件。Class类对象阶段:*.class字节码文件被类加载器加载进内存,并将其封装成Class对象(用于在内存中描述字节码文件),Class对象将原字节码文件中的成员变量抽取出来封装成数组Field[],将原字节码文件中的构造函数抽取出来封装成数组Construction[],在将成员方法封装成Method[]。当然Class类内不止这三个,还封装了很多,我们常用的就这三个。RunTime运行时阶段:创建对象的过程new。获取Class对象的方式:Class.forname( 类全名 ):将字节码加载进内存,返回Class对象。一般用于: 配置文件,将类名定义在配置文件中,读取文件,加载类。类名.class:通过类名的属性Class获取一般用于: 参数传递对象.getclass()获取:getclass()方法在Object类中定义一般用于: 对象获取字节码的方式补充:同一个字节码文件(*.class)在一次程序运行中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。fyz爱图古源码汇
举例:fyz爱图古源码汇
fyz爱图古源码汇
1 获取成员变量们fyz爱图古源码汇
Field[] getFields() :获取所有public修饰的成员变量Field getField(String name) 获取指定名称的 public修饰的成员变量Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符Field getDeclaredField(String name)//需要忽略访问权限修饰符的安全检查 setAccessible(true):暴力反射,不然会报错具体测试看下文!fyz爱图古源码汇
2.获取构造方法们fyz爱图古源码汇
Constructor ? [] getConstructors() Constructor T getConstructor(类 ? ... parameterTypes) Constructor ? [] getDeclaredConstructors() Constructor T getDeclaredConstructor(类 ? ... parameterTypes)具体测试看下文!fyz爱图古源码汇
3.获取成员方法们:fyz爱图古源码汇
Method[] getMethods() Method getMethod(String name, 类 ? ... parameterTypes) Method[] getDeclaredMethods() Method getDeclaredMethod(String name, 类 ? ... parameterTypes)//需要忽略访问权限修饰符的安全检查 setAccessible(true):暴力反射,不然会报错具体测试看下文!fyz爱图古源码汇
4.获取全类名fyz爱图古源码汇
String getName()getClass()方法是Object类的方法,需要注意一点获取的类名是全类名(带有路径)举例:fyz爱图古源码汇
package Test;public class Reflect { public static void main(String[] args) throws Exception { Class Tst = Test.class; String s=Tst.getName(); System.out.println(s);运行结果:fyz爱图古源码汇
举例:fyz爱图古源码汇
package Test;public class Test { public String a; protected String b; private String c; String d; Test tst=new Test(); System.out.println( -------------------测试getField-------------------- Field[] fields=Tst.getFields(); for(Field f:fields) System.out.println(f); Field a=Tst.getField( a a.set(tst, 我是设置值 System.out.println(a.get(tst)); System.out.println( \n-------------测试getDeclaredField------------------ Field[] fields2=Tst.getDeclaredFields(); for(Field f:fields2) f.setAccessible(true);//不加出不来,详情请看上文 System.out.println(f); Field b=Tst.getDeclaredField( b b.set(tst, 我是私有的设置值 System.out.println(b.get(tst));测试结果:fyz爱图古源码汇
创建对象:T newInstance(Object... initargs)注意:如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法作用就是用它来创建对象举例:fyz爱图古源码汇
package Test;public class Test { public String a; //构造方法 public Test( ) {} public Test(String a) { this.a = a;package Test;import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class Reflect { public static void main(String[] args) throws Exception { Class Tst = Test.class; Constructor[] constructors = Tst.getConstructors(); for (Constructor constructor : constructors) { // Constructor 对象reflect包下的 import java.lang.reflect.Constructor; System.out.println(constructor); System.out.println( ------------------无参构造函数创建对象---------------------- Constructor cst=Tst.getConstructor(); //获得无参构造函数 System.out.println(cst); Object test=cst.newInstance(); //利用无参构造函数创建对象 System.out.println(test); System.out.println( ------------------有参构造函数创建对象---------------------- Constructor cst2=Tst.getConstructor(String.class); //获得有参构造函数 System.out.println(cst2); Object test2=cst2.newInstance( 张3 //利用有参构造函数创建对象 System.out.println(test2); System.out.println( ------------------基于Class创建对象---------------------- Object test3=Tst.newInstance(); //只能用于无参构函数,而且已经被弃用,不建议使用 System.out.println(test3);喜欢问问题的小朋友要来了?为什么没有getDeclaredConstructor方法和getDeclaredConstructors方法?为什么?为什么?有啊!!getDeclaredConstructor方法可以获取到任何访问权限的构造器,而getConstructor方法只能获取public修饰的构造器。具体不再测试。此外在构造器的对象内也有setAccessible(true);方法,并设置成true就可以操作了。关于为什么要使用private访问权限的构造器,使用这个构造器不就不能外部访问了嘛,不也就无法进行实例化对象了吗?无法在类的外部实例化对象正是私有构造器的意义所在,在单例模式下经常使用,整个项目只有一个对象,外部无法实例化对象,可以在类内的进行实例化并通过静态方法返回,由于实例化的对象是静态的,故只有一个对象,也就是单例的,这就是单例模式中的饿汉模式,不管是否调用,都创建一个对象。fyz爱图古源码汇
执行方法:Object invoke(Object obj, Object... args)获取方法名称:String getName();fyz爱图古源码汇
举例:fyz爱图古源码汇
package Test;public class Test { public String a; // 构造方法 public Test() { public Test(String a) { this.a = a; public void do_Something() { System.out.println( 吃饭睡觉打豆豆 public String do_Something(String s) { System.out.println( 吃饭睡觉打 +s); return 爽运行结果:举例2.0:fyz爱图古源码汇
运行结果:fyz爱图古源码汇
这时候又会有小朋友问:为什么要这么麻烦,我直接调用不就好了?fyz爱图古源码汇
不知你是否发现,从类的创建的方法的使用,所有的一切都是用的字符串,那么也就是说,我可以通过读入数据,或者配置文件的方式,创建类,调用方法。fyz爱图古源码汇
举个简单点的例子:就拿英雄联盟这款游戏来说,这游戏三天两头的轮换一个娱乐模式,难道每次上线都要对源代码进行修改,今天在Client调用“无限活力”,明天就要调用 魄罗大乱斗”,每天就对着源码改?几万行的代码就这么放心让你改?除非你老板想做空公司,故意的!必然不可能,这时候我们就算哪一个txt文件,就放一行字符串,用反射之后,只用改txt文件不就完了!不用反射,是做不到用字符串创建类,和运行方法(别抬杠,写个if-else 或者 switch啥的)。fyz爱图古源码汇
举例可能不太恰当,一般不会使用txt,一般使用XML或者java配置文件。fyz爱图古源码汇
写在最后:我叫风骨散人,名字的意思是我多想可以不低头的自由生活,可现实却不是这样。家境贫寒,总得向这个世界低头,所以我一直在奋斗,想改变我的命运给亲人好的生活,希望同样被生活绑架的你可以通过自己的努力改变现状,深知成年人的世界里没有容易二字。目前是一名在校大学生,预计考研,热爱编程,热爱技术,喜欢分享,知识无界,希望我的分享可以帮到你!如果有什么想看的,可以私信我,如果在能力范围内,我会发布相应的博文!感谢大家的阅读!😘你的点赞、收藏、关注是对我最大的鼓励!fyz爱图古源码汇
免责申明:注册会员下载资源前请仔细阅读《本站条款》本站所有资源都来自于网络,版权归原创者所有!本站网络资源不提供任何售后和服务,也不承担任何法律责任,如有侵权或危害了你的利益,请出示相应的资质证明并联系站长,我们将马上予以删除。来源:爱图古源码网(站长邮箱:a13879801652@foxmail.com 转载请保留出处!) 本文地址:https://www.aitgoo.com/wangluo/28642.html相关关键词: