谁来帮用量子是什么 通俗易懂懂的语言解释下java的反射机制

谁来帮用通俗易懂的语言解释下java的反射机制_java吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:640,953贴子:
谁来帮用通俗易懂的语言解释下java的反射机制收藏
RT~~万分感谢,百度的内容都看不懂啊
智联招聘,每天更新350万高薪招聘java程序员信息,真实有效,24小时极速反馈,立即登录填写简历,快速找到好工作!
根据类名生成类的对象
登录百度帐号推荐应用Java的反射机制是什么,如何实现?
来源:it-home
本文和大家分享的是java语言/course/234/的反射机制及相关应用场景。其实JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制。  反射机制提供了哪些功能?  ·在运行时判定任意一个对象所属的类  ·在运行时构造任意一个类的对象;  ·在运行时判定任意一个类所具有的成员变量和方法;  ·在运行时调用任意一个对象的方法;  ·生成动态代理;  Java反射机制类:  java.lang.C //类  java.lang.reflect.C//构造方法  java.lang.reflect.F //类的成员变量  java.lang.reflect.M//类的方法  java.lang.reflect.M//访问权限  Java反射机制实现:  1.)class对象的获取  //第一种方式 通过对象getClass方法  Person person = new Person();Class class1 = person.getClass();//第二种方式 通过类的class属性&/?&  class1 = Person.class;try {  //第三种方式 通过Class类的静态方法——forName()来实现  class1 = Class.forName("com.whoislcj.reflectdemo.Person");  } catch (ClassNotFoundException e) {  e.printStackTrace();  }  2.)获取class对象的摘要信息  boolean isPrimitive = class1.isPrimitive();//判断是否是基础类型boolean isArray = class1.isArray();//判断是否是集合类boolean isAnnotation = class1.isAnnotation();//判断是否是注解类boolean isInterface = class1.isInterface();//判断是否是接口类boolean isEnum = class1.isEnum();//判断是否是枚举类boolean isAnonymousClass = class1.isAnonymousClass();//判断是否是匿名内部类boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);//判断是否被某个注解类修饰  String className = class1.getName();//获取class名字 包含包名路径Package aPackage = class1.getPackage();//获取class的包信息  String simpleName = class1.getSimpleName();//获取class类名int modifiers = class1.getModifiers();//获取class访问权限  Class[] declaredClasses = class1.getDeclaredClasses();//内部类Class declaringClass = class1.getDeclaringClass();//外部类&/?&&/?&  3.)获取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对象的直接超类的 TypeType[] interfaceTypes = class1.getGenericInterfaces();//获取class对象的所有接口的type集合  4.)class对象动态生成  //第一种方式 Class对象调用newInstance()方法生成Object obj = class1.newInstance();//第二种方式 对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成Constructor constructor =class1.getDeclaredConstructor(new Class[]{String.class});//获取指定声明构造函数&/?&  obj = constructor.newInstance(new Object[]{"lcj"});  5.)动态调用函数  try {  // 生成新的对象:用newInstance()方法  Object obj = class1.newInstance();  //判断该对象是否是Person的子类  boolean isInstanceOf = obj instanceof P  //首先需要获得与该方法对应的Method对象  Method method = class1.getDeclaredMethod("setAge", new Class[]{int.class});  //调用指定的函数并传递参数  method.invoke(obj, 28);  method = class1.getDeclaredMethod("getAge");  Object result = method.invoke(obj, new Class[]{});  } catch (InstantiationException e) {  e.printStackTrace();  } catch (IllegalAccessException e) {  e.printStackTrace();  } catch (NoSuchMethodException e) {  e.printStackTrace();  } catch (InvocationTargetException e) {  e.printStackTrace();  }  6.)通过反射机制获取泛型类型  例如下面这种结构  //People类  public class People {}//Person类继承People类  public class Person extends People implements PersonInterface {}//PersonInterface接口  public interface PersonInterface{}  获取泛型类型  Personperson = new Person&&();//第一种方式 通过对象getClass方法  Class class1 = person.getClass();&/?&  Type genericSuperclass = class1.getGenericSuperclass();//获取class对象的直接超类的 Type  Type[] interfaceTypes = class1.getGenericInterfaces();//获取class对象的所有接口的Type集合  getComponentType(genericSuperclass);  getComponentType(interfaceTypes[0]);  getComponentType具体实现  private Class getComponentType(Type type) {&/?&  Class componentType =if (type instanceof ParameterizedType) {&/?&  //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。  Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();  if (actualTypeArguments != null && actualTypeArguments.length & 0) {  componentType = (Class) actualTypeArguments[0];&/?&  }  } else if (type instanceof GenericArrayType) {  // 表示一种元素类型是参数化类型或者类型变量的数组类型  componentType = (Class) ((GenericArrayType) type).getGenericComponentType();&/?&  } else {  componentType = (Class)&/?&  }return componentT  }  6.)通过反射机制获取注解信息  这里重点以获取Method的注解信息为例  try {  //首先需要获得与该方法对应的Method对象  Method method = class1.getDeclaredMethod("jumpToGoodsDetail", new Class[]{String.class, String.class});  Annotation[] annotations1 = method.getAnnotations();//获取所有的方法注解信息  Annotation annotation1 = method.getAnnotation(RouterUri.class);//获取指定的注解信息  TypeVariable[] typeVariables1 = method.getTypeParameters();  Annotation[][] parameterAnnotationsArray = method.getParameterAnnotations();//拿到所有参数注解信息  Class[] parameterTypes = method.getParameterTypes();//获取所有参数class类型&/?&  Type[] genericParameterTypes = method.getGenericParameterTypes();//获取所有参数的type类型  Class returnType = method.getReturnType();//获取方法的返回类型&/?&  int modifiers = method.getModifiers();//获取方法的访问权限  } catch (NoSuchMethodException e) {  e.printStackTrace();  }  反射机制的应用场景:  · 逆向代码 ,例如反编译  · 与注解相结合的框架 例如Retrofit  · 单纯的反射机制应用框架 例如EventBus 2.x  · 动态生成类框架 例如Gson  反射机制的优缺点:  优点:  运行期类型的判断,动态类加载,动态代理使用反射。  缺点:  性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的要慢很多。  总结:  Java的反射机制在平时的业务开发过程中很少使用到,但是在一些基础框架的搭建上应用非常广泛,今天简单的总结学习了一下,还有很多未知的知识等以后用到再做补充。文章来源:麦穗技术
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动    序言
      在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射,所以回过头来把这个给重新补一下,自己欠下的债,迟早是要还的。
                                      ---WH
一、什么是反射?
    在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。
    想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。
    获取字节码文件对象的三种方式。
       1、Class clazz1 = Class.forName("全限定类名");  //通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。
       2、Class clazz2& = Person.    //当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。
       3、Class clazz3 = p.getClass();    //通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段 
    有了字节码文件对象才能获得类中所有的信息,我们在使用反射获取信息时,也要考虑使用上面哪种方式获取字节码对象合理,视不同情况而定。下面介绍Class类的功能。
二、反射机制能够获取哪些信息?Class类的API详解。
    2.1、通过字节码对象创建实例对象
         
    2.2、获取指定构造器方法。constructor 如果没有无参构造,只有有参构造如何创建实例呢?看下面
         
      总结上面创建实例对象:Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了,可以调用Class类的                             getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象
      获取全部构造方法  
              
    2.3、获取成员变量并使用  Field对象
         获取指定成员变量
          
        &Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取,通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
        获取全部成员变量
        
    2.4、获得方法并使用  Method
          
        Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法,    
          如果为私有方法,则需要打开一个权限。setAccessible(true);
        用invoke(Object, Object...)可以调用该方法,
        跟上面同理,也能一次性获得所有的方法
          
               
    2.5、获得该类的所有接口
         Class[] getInterfaces():确定此对象所表示的类或接口实现的接口
         返回值:接口的字节码文件对象的数组
    2.6、获取指定资源的输入流
         InputStream getResourceAsStream(String name)  
         return:一个 InputStream 对象;如果找不到带有该名称的资源,则返回 null
         参数:所需资源的名称,如果以"/"开始,则绝对资源名为"/"后面的一部分。
    2.7、动态代理的概述和实现
       动态代理:一种设计模式,其非常简单,很容易理解,你自己可以做这件事,但是觉得自己做非常麻烦或者不方便,所以就叫一个另一个人(代理)来帮你做这个事情,而你就不用管了,这就是动态代理。举个例子,买火车票叫人代买。&
       在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理
       在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib,Proxy类中的方法创建动态代理类对象 
        分三步,但是注意JDK提供的代理正能针对接口做代理,也就是下面的第二步返回的必须要是一个接口。
       1、new出代理对象,通过实现InvacationHandler接口,然后new出代理对象来。
       2、通过Proxy类中的静态方法newProxyInstance,来将代理对象假装成那个被代理的对象,也就是如果叫人帮我们代买火车票一样,那个代理就假装成我们自己本人
       3、执行方法,代理成功
          将代理对象中的内容进行实现
               
             
          
        1、2、3步
          
        注意newProxyInstance的三个参数,第一个,类加载器,第二个被代理对象的接口,第三个代理对象。  
       
    2.8、还有很多方法,比如获得类加载器,等等
       具体还需要别的,就通过查看API文档来解决。
三、反射机制的应用实例
    3.1、利用反射,在泛型为int的arryaList集合中存放一个String类型的对象
       原理:集合中的泛型只在编译器有效,而到了运行期,泛型则会失效,
         
   3.2、利用反射,简化编写Servlet的个数。
        什么意思呢?每当我们写一个功能时,就需要写一个对应的Servlet,导致最后Servlet有很多,自己都看不过来,所以对其进行了优化,两种方式,
        3.2.1、每次从页面传过来一个参数,method="xxx"; 然后编写一个Servlet,获得其参数method的值,进行判断,如果是add,则调用add方法,如果是delete,则调用delete方法,这样就可以写在一个servlet中实现所有的功能了。 
        
      3.2.2、利用反射
        编写一个BaseServlet继承HttpServlet,这是一个通用的BaseServlet。需要明白servlet的生命周期
        
        编写具体实现的方法servlet类。
        MySerlvet001 extends BaseServlet
        
        
        解释:需要明白servlet的生命周期,也就是service方法,因为是servlet,所以在访问的时候,会经过service方法,而子类MyServlet001中并没有,所以就到父类BaseServlet中找,发现有,然后获取参数即知道了需要调用什么方法,因为方法的编写都在子类中,所以通过反射,获取到子类中对应的方法并运行,其中需要注意的是this这个参数在BaseServlet中的用法。需要理解它。才能理解我们这个程序。
      反射基本上就这样讲完了,其实就是对其一些api进行讲解,不懂的就查看API,重要的思想,就要在实际中遇到了才能得到更好的理解。先这样过一遍,零零碎碎的知识。
阅读(...) 评论()安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&}

我要回帖

更多关于 通俗易懂 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信