什么是Java的反射机制
时间 2019-12-07
标签
什么
java
反射
机制
Java反射机制是Java的特色,是框架实现的基础,百度结果:JAVA反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。java一般是先有类再有对象,有对象我就能够调用方法或者属性。反射实际上是经过Class对象来调用类里面的方法。经过反射能够调用私有方法和私有属性。大部分框架都是运用反射原理,精简总结一下: 1.什么是反射 答:就是能够在程序运行的时候动态装载类,查看类的信息,生成对象,或操做生成对象。类在运行的时候,能够获得该类的信息,而且 能够动态的修改这些信息,本身能看到本身,跟照镜子同样,也就是说Java的反射机制是在编辑的时候并不肯定哪一个类被加载了,而是在程序运行的时候才加载、探知、自审,使用在编译期并不知道的类,这样的特色就是反射。 2.那么Java反射有什么做用呢? 假如咱们有两个程序员,一个程序员在写程序的时候,须要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码可否经过编译呢?这是不能经过编译的。利用Java反射的机制,就可让第一个程序员在没有获得第二个程序员所写的类的时候,来完成自身代码的编译。Java反射机制主要提供了如下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具备的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,咱们称为Java类的“自审”。你们都用过Jcreator和eclipse。 当咱们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象可以使用的全部的方法和属性所有都列出来,供用户进行 选择。这就是利用了Java反射的原理,是对咱们建立对象的探知、自审。 3.反射技术大量用于Java设计模式和框架技术,最多见的设计模式就是工厂模式和单例模式。 单例模式(Singleton) 这个模式主要做用是保证在Java应用程序中,一个类Class只有一个实例存在。在不少操做中,好比创建目录 数据库链接都须要这样的单线程操做。这样作就是为了节省内存空间,保证咱们所访问到的都是同一个对象。 单例模式要求保证惟一,那么怎么样才能保证惟一性呢?对了,这就是静态变量。单例模式有如下两种形式: 第一种形式: package reflect; public class Singleton { private Singleton() { } private static Singleton instance = new Singleton(); // 这里提供了一个供外部访问本class的静态方法,能够直接访问 public static Singleton getInstance() { return instance; } } class SingRun{ public static void main(String[] args){ //这样的调用不被容许,由于构造方法是私有的。 //Singleton x=new Singleton(); //获得一个Singleton类实例 Singleton x=Singleton.getInstance(); //获得另外一个Singleton类实例 Singleton y=Singleton.getInstance(); //比较x和y的地址,结果为true。说明两次得到的是同一个对象 System.out.println(x==y); } } 第二种形式: public class Singleton { //先申明该类静态对象 private static Singleton instance = null; //建立一个静态访问器,得到该类实例。加上同步,表示防止两个线程同时进行对象的建立 public static synchronized Singleton getInstance() { //若是为空,则生成一个该类实例 if (instance == null){ instance = new Singleton(); } return instance; } } 工厂模式(Factory) 工厂模式是咱们最经常使用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统能够说是随处可见。 为何工厂模式是如此经常使用?是由于工厂模式利用Java反射机制和Java多态的特性可让咱们的程序更加具备灵活性。用工厂模式进行大型项目的开发,能够很好的进行项目并行开发。就是一个程序员和另外一个程序员能够同时去书写代码,而不是一个程序员等到另外一个程序员写完之后再去书写代码。其中的粘合剂就是接口和配置文件。以前说利用接口能够将调用和实现相分离。那么这是怎么样去实现的呢?工厂模式能够为咱们解答。 咱们先来回顾一下软件的生命周期,分析、设计、编码、调试与测试。其中分析就是指需求分析,就是知道这个软件要作成什么样子,要实现什么样的功能。功能知道了,这时就要设计了。设计的时候要考虑到怎么样高效的实现这个项目,若是让一个项目团队并行开发。这时候,一般先设计接口,把接口给实现接口的程序员和调用接口的程序员,在编码的时候,两个程序员能够互不影响的实现相应的功能,最后经过配置文件进行整合。 代码示例: interface InterfaceTest{ public void getName();//定义得到名字的方法 } 接口有了,那么获得这个接口,进行实现编码的程序员应该怎么作呢?对了,实现这个接口,重写其中定义的方法 接口实现方法: class Test1 implements InterfaceTest{ public void getName() { System.out.println("test1"); } } class Test2 implements InterfaceTest{ public void getName() { System.out.println("test2"); } } 你们能够发现,当接口定义好了之后,不但能够规范代码,并且可让程序员有条不紊的进行功能的实现。实现接口的程序员根本不用去管,这个类要被谁去调用。 那么怎么能得到这些程序员定义的对象呢?在工厂模式里,单独定义一个工厂类来实现对象的生产,注意这里返回的接口对象。 工厂类,生产接口对象: class Factory{ //建立私有的静态的Properties对象 private static Properties pro=new Properties(); //静态代码块 static{ try { //加载配置文件 pro.load(new FileInputStream("file.txt")); } catch (Exception e) { e.printStackTrace(); } } private static Factory factory=new Factory(); private Factory(){} public static Factory getFactory(){ return factory; } public InterfaceTest getInterface(){ InterfaceTest interfaceTest=null;//定义接口对象 try { //根据键,得到值,这里的值是类的全路径 String classInfo=pro.getProperty("test"); //利用反射,生成Class对象 Class c=Class.forName(classInfo); //得到该Class对象的实例 Object obj=c.newInstance(); //将Object对象强转为接口对象 interfaceTest=(InterfaceTest)obj; } catch (Exception e) { e.printStackTrace(); } //返回接口对象 return interfaceTest; } } 配置文件内容: test=factory.Test2 经过这个类,你们能够发现,在调用的时候,获得的是个接口对象。而一个接口变量能够指向实现了这个接口的类对象。在利用反射的时候,咱们并无直接把类的 全路径写出来,而是经过键得到值。这样的话,就有很大的灵活性,只要改变配置文件里的内容,就能够改变咱们调用的接口实现类,而代码不需作任何改变。在调 用的时候,咱们也是经过接口调用,甚至咱们能够连这个接口实现类的名字都不知道。 调用方法: public class FactoryTest { public static void main(String[] args) { //得到工厂类的实例 Factory factory=Factory.getFactory(); //调用得到接口对象的方法,得到接口对象 InterfaceTest inter=factory.getInterface(); //调用接口定义的方法 inter.getName(); } } 上面的代码就是调用方法。你们能够发现,在调用的时候,咱们根本没有管这个接口定义的方法要怎么样去实现它,咱们只知道这个接口定义这个方法起什么做用就好了。上面代码运行结果要根据配置文件来定。若是配置文件里的内容是test=factory.Test2。那么表示调用factory.Test2这个 类里实现接口的方法,这时候打印“test2”。若是配置文件里的内容是test=factory.Test1。那么表示调用factory.Test1 这个类里实现接口的方法,这时候打印“test1”。