08.Java反射问题

目录介绍

  • 8.0.0.1 反射的原理是什么?有哪些途径获取到Class对象,Class类的含义和做用是什么?什么是class类?
  • 8.0.0.2 有哪些方式能够提升反射效率?为什么反射消耗性能?到底是怎么影响的,举例说明?
  • 8.0.0.3 java反射机制提供了什么功能?发射具备暴力访问权限,如何防止反射序列化***单例?
  • 8.0.0.4 经过反射得到泛型的实际类型参数?反射获取构造方法,变量,方法的方法是哪些?
  • 8.0.0.5 getGenericParameterTypes 与 getParameterTypes区别?
  • 8.0.0.6 反射有什么做用和应用?反射和注解相比,为什么反射消耗性能,有什么优缺点?

好消息

  • 博客笔记大汇总【15年10月到至今】,包括Java基础及深刻知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,固然也在工做之余收集了大量的面试题,长期更新维护而且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计500篇[近100万字],将会陆续发表到网上,转载请注明出处,谢谢!
  • 连接地址:https://github.com/yangchong211/YCBlogs
  • 若是以为好,能够star一下,谢谢!固然也欢迎提出建议,万事起于忽微,量变引发质变!全部博客将陆续开源到GitHub!

8.0.0.1 反射的原理是什么?有哪些途径获取到Class对象,Class类的含义和做用是什么?什么是class类?

  • 反射的原理是什么?
    • 反射是为了可以动态的加载一个类,动态的调用一个方法,动态的访问一个属性等动态要求而设计的。它的出发点就在于JVM会为每一个类建立一个java.lang.Class类的实例,经过该对象能够获取这个类的信息,而后经过使用java.lang.reflect包下得API以达到各类动态需求。
    • 反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
  • 有哪些途径获取到Class对象,Class类的含义和做用是什么?
    • 每个Class类的对象就表明了一种被加载进入JVM的类,它表明了该类的一种信息映射。开发者能够经过3种途径获取到Class对象。
    • 技术博客大总结
    • 第一种方式:Class的forName()方法的返回值就是Class类型,也就是动态导入类的Class对象的引用。
    • public static Class<?> forName(String className) throws ClassNotFoundException
    • 第二种方式:每一个类都会有一个名称为Class的静态属性,经过它也是能够获取到Class对象的,示例代码以下:
      Class<Student> clazz = Student.class;   // 访问Student类的class属性
    • 第三种方式:Object类中有一个名为getClass的成员方法,它返回的是对象的运行时类的Class对象。由于Object类是全部类的父类,因此,全部的对象均可以使用该方法获得它运行时类的Class对象,示例代码以下:
      Student stu = new Student();
      Class<Student> clazz = stu.getClass();   // 调用Student对象的getName方法
  • 什么是class类?
    • .class文件:是由一个.java文件经过编译过程生成的.class文件。Class对象:当Java虚拟机加载一个.class文件到内存时,都会生成一个对应的Class对象,注意的是这个Class对象有且只有一个存在于内存当中。

8.0.0.2 有哪些方式能够提升反射效率?为什么反射消耗性能?到底是怎么影响的,举例说明?

  • 有哪些方式能够提升反射效率?php

    • 善用API:好比,尽可能不要getMethods()后再遍历筛选,而直接用getMethod(methodName)来根据方法名获取方法。
    • 技术博客大总结
    • 适当使用缓存:好比,须要屡次动态建立一个类的实例的时候,有缓存的写法会比没有缓存要快不少:
      // 1. 没有缓存
      void createInstance(String className){
      return Class.forName(className).newInstance();
      }

    // 2. 缓存forName的结果
    void createInstance(String className){
    cachedClass = cache.get(className);
    if (cachedClass == null){
    cachedClass = Class.forName(className);
    cache.set(className, cachedClass);
    }
    return cachedClass.newInstance();
    }java

     
  • 为什么反射消耗性能?

8.0.0.3 java反射机制提供了什么功能?发射具备暴力访问权限,如何避免反射***?

  • java反射机制提供了什么功能?
    • 在运行时可以判断任意一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时判断任意一个类所具备的成员变量和方法
    • 在运行时调用任一对象的方法技术博客大总结
    • 在运行时建立新类对象
  • 发射具备暴力访问权限,如何避免反射***?
  • 如何防止反射序列化***单例git

    • 枚举单例
      public enum Singleton {
          INSTANCE {
              @Override
              protected void read() {
                  System.out.println("read");
              }
              @Override
              protected void write() {
                  System.out.println("write");
              }
          };
          protected abstract void read();
          protected abstract void write();
      }
    • class文件:github

      public abstract class Singleton extends Enum{
          private Singleton(String s, int i){
              super(s, i);
          }
      
          protected abstract void read();
          protected abstract void write();
          public static Singleton[] values(){
              Singleton asingleton[];
              int i;
              Singleton asingleton1[];
              System.arraycopy(asingleton = ENUM$VALUES, 0, asingleton1 = new Singleton[i = asingleton.length], 0, i);
              return asingleton1;
          }
      
          public static Singleton valueOf(String s) {
              return (Singleton)Enum.valueOf(singleton/Singleton, s);
          }
      
          Singleton(String s, int i, Singleton singleton){
              this(s, i);
          }
      
          public static final Singleton INSTANCE;
          private static final Singleton ENUM$VALUES[];
      
          static {
              INSTANCE = new Singleton("INSTANCE", 0){
      
                  protected void read(){
                      System.out.println("read");
                  }
      
                  protected void write(){
                      System.out.println("write");
                  }
      
              };
              ENUM$VALUES = (new Singleton[] {
                  INSTANCE
              });
          }
      }
      • 类的修饰abstract,因此无法实例化,反射也无能为力。关于线程安全的保证,实际上是经过类加载机制来保证的,咱们看看INSTANCE的实例化时机,是在static块中,JVM加载类的过程显然是线程安全的。对于防止反序列化生成新实例的问题还不是很明白,通常的方法咱们会在该类中添加上以下方法,不过枚举中也没有显示的写明该方法。技术博客大总结
        //readResolve to prevent another instance of Singleton
        private Object readResolve(){
        return INSTANCE;
        }

8.0.0.4 经过反射得到泛型的实际类型参数?反射获取构造方法,变量,方法的方法是哪些?

  • 经过反射得到泛型的实际类型参数面试

    • 把泛型变量当成方法的参数,利用Method类的getGenericParameterTypes方法来获取泛型的实际类型参数
    • 例子:segmentfault

      public class GenericTest {
      
          public static void main(String[] args) throws Exception {
              getParamType();
          }
      
           /*利用反射获取方法参数的实际参数类型*/
          public static void getParamType() throws NoSuchMethodException{
              Method method = GenericTest.class.getMethod("applyMap",Map.class);
              //获取方法的泛型参数的类型
              Type[] types = method.getGenericParameterTypes();
              System.out.println(types[0]);
              //参数化的类型
              ParameterizedType pType  = (ParameterizedType)types[0];
              //原始类型
              System.out.println(pType.getRawType());
              //实际类型参数
              System.out.println(pType.getActualTypeArguments()[0]);
              System.out.println(pType.getActualTypeArguments()[1]);
          }
      
          /*供测试参数类型的方法*/
          public static void applyMap(Map<Integer,String> map){
      
          }
      
      }
    • 输出结果:
      java.util.Map<java.lang.Integer, java.lang.String>
      interface java.util.Map
      class java.lang.Integer
      class java.lang.String
  • 反射获取构造方法,变量,方法的方法是哪些?技术博客大总结
    • 在反射包中,咱们经常使用的类主要有Constructor类表示的是Class 对象所表示的类的构造方法,利用它能够在运行时动态建立对象、Field表示Class对象所表示的类的成员变量,经过它能够在运行时动态修改为员变量的属性值(包含private)、Method表示Class对象所表示的类的成员方法,经过它能够动态调用对象的方法(包含private)。

8.0.0.5 getGenericParameterTypes 与 getParameterTypes区别?

  • getGenericParameterTypes 与 getParameterTypes区别?
    • getGenericParameterTypes 与 getParameterTypes 都是获取构成函数的参数类型
    • 前者返回的是Type类型,后者返回的是Class类型,因为Type顶级接口,Class也实现了该接口,所以Class类是Type的子类,Type 表示的所有类型而每一个Class对象表示一个具体类型的实例,如String.class仅表明String类型。由此看来Type与 Class 表示类型几乎是相同的,只不过Type表示的范围比Class要广得多而已。固然Type还有其余子类,如:
      • TypeVariable:表示类型参数,能够有上界,好比:T extends Number
      • ParameterizedType:表示参数化的类型,有原始类型和具体的类型参数,好比:List<String>
      • WildcardType:表示通配符类型,好比:?, ? extends Number, ? super Integer

8.0.0.6 反射有什么做用和应用?反射和注解相比,为什么反射消耗性能,有什么优缺点?

  • 反射有什么做用和应用?
    • 含义:在运行状态中,对于任意一个类都能知道它的全部属性和方法,对于任何一个对象都可以调用它的任何一个方法和属性。
    • 功能:动态性,体如今:在运行时判断任意一个类所具备的属性和方法; 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时调用任意一个对象的方法;生成动态代理
  • 为什么反射消耗性能
  • 有什么优缺点
    • 优势
      • 动态编译:运行时肯定类型,绑定对象。动态编译最大限度的发挥了java的灵活性,体现了多态的应用,有利于下降类之间的耦合性。
      • 反射机制的优势就是能够实现动态建立对象和编译,体现出很大的灵活性,特别是在开发中。它的灵活性就表现的十分明显。好比,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现须要更新某些功能时,咱们不可能要用户把之前的卸载,再从新安装新的版本,假如这样的话,这个软件确定是没有多少人用的。采用静态的话,须要把整个程序从新编译一次才能够实现功能的更新,而采用反射机制的话,它就能够不用卸载,只须要在运行时才动态的建立和编译,就能够实现该功能。

其余介绍

01.关于博客汇总连接

02.关于个人博客

相关文章
相关标签/搜索