首页 > 编程学习 > 【Java八股文总结】之反射

【Java八股文总结】之反射

发布时间:2022/11/20 15:53:28

文章目录

    • Java反射
      • 一、泛型
        • 1、何为泛型?
        • 2、泛型通配符
          • Q:泛型擦除是什么?
        • 3、泛型上限和下限
      • 二、反射
        • 1、何为反射?
        • 2、反射有什么用?
        • 3、反射应用场景有哪些?
          • Q:反射的优缺点?
        • 4、反射获取Class类对象的4种方式
        • 5、反射API有几类?
        • 6、反射获取实例化对象
      • 三、代理模式
        • 1、代理模式
        • 2、静态代理
        • 3、动态代理
          • 1、JDK动态代理机制
            • Q:为什么 JDK 动态代理要基于接口实现?而不是基于继承来实现?
            • Q:JDK 动态代理中,目标对象调用自己的另一个方法,会经过代理对象吗?
            • Q:为什么不使用静态代理而使用动态代理?
          • 2、CGLIB动态代理机制
          • 3、JDK动态代理和CGLIB动态代理比较
          • 4、静态代理和动态代理比较
      • 四、注解
        • 1、何为注解?
          • Q:注解的解析方法有?

Java反射

一、泛型

1、何为泛型?

泛型(Generics),是指在定义时不指定信息的具体数据类型,而是暂时用一个 标识符 来代替,当外部实例化对象的时候再来指定具体的数据类型 (定义时不指定,使用标识符代替,使用时指定)。
优点: 极大提升程序的灵活性,提升类/接口的拓展性,泛型可以指代类中成员变量的数据类型,方法的返回值类型以及方法的参数类型。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、泛型通配符

? 表示可以任意类型的泛型对象。

Q:泛型擦除是什么?

所谓的泛型擦除,官方名叫“类型擦除”。
Java的泛型是伪泛型,这是因为Java在编译期间,所有的类型信息都会被擦掉。
也就是说,在运行的时候是没有泛型的

3、泛型上限和下限

  1. 泛型上限(最大类型,小于等于上限才可以):表示实例化时具体的数据类型,可以是 上限类型的子类或者时上限类型本身 ,用 extends 表示。
    使用:类名 <泛型标识 extends 上限类名>
  2. 泛型下限(最小类型,大于等于下限都可以):表示实例化时具体的数据类型,可以是 下限类型的父类或者是下限类型本身,用 super 表示。
    使用:类名 <泛型标识 super 下限类名>

二、反射

1、何为反射?

JAVA反射机制是在 运行状态 中,对于任意一个类,都能够知道这个 类的所有属性和方法 ;对于任意一个对象,都能够调用它的任意一个方法和属性;这种 动态获取的信息以及动态调用对象方法的功能 称为java语言的反射机制。
反射就是在运行时获取类的 所有属性和方法(如构造器、成员变量、成员方法),得到编译后的class文件对象 是Java反射的核心。

2、反射有什么用?

通过java语言中的反射机制可以 操作字节码文件(可以读和修改字节码文件。)通过反射机制可以操作代码片段(class文件)。

3、反射应用场景有哪些?

如常见的 SSM框架中、动态代理、注解 等。
在这里插入图片描述

Q:反射的优缺点?

在这里插入图片描述

4、反射获取Class类对象的4种方式

在这里插入图片描述

5、反射API有几类?

在这里插入图片描述

反射 API 用来生成 JVM 中的 类、接口或对象 的信息。
① Class类: 反射的核心类,可以获取类的属性,方法等信息。
② Field类: Java.lang.reflect 包中的类,表示类的成员变量,可以用来获取和设置类中的属性值。
③ Method类: Java.lang.reflect 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
④ Constructor类: Java.lang.reflect 包中的类,表示类的构造方法。
⑤ Annotation类: 类的注解。

6、反射获取实例化对象

取得Class类对象的一个最直接的好处就是 通过反射实例化对象,该方法为:

  • 对象.newInstance()
    注:newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以 ,否则会抛出java.lang.InstantiationException异常。

三、代理模式

在这里插入图片描述
在这里插入图片描述
注意: JDK 动态代理有一个最致命的问题是其 只能代理实现了接口的类。(即一个类没有实现接口,那么JDK动态代理无法代理)

1、代理模式

在这里插入图片描述

2、静态代理

静态代理:手动编写代理类,实现接口(接口一旦改动,代理类和实现类都需要修改)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、动态代理

动态代理是在 运行时 动态生成类字节码,并加载到JVM中,不需要手动创建代理类、实现接口,可以直接代理实现类。
常见的动态代理,如 JDK动态代理、CGLIB动态代理 等。
在这里插入图片描述

1、JDK动态代理机制

通过 反射 来接收被代理的类,在不改变原来目标方法功能的前提下,在代理中增强自己的功能代码。并且要求 被代理的类必须实现一个接口
JDK动态代理的核心 是InvocationHandler接口和Proxy类。

Q:为什么 JDK 动态代理要基于接口实现?而不是基于继承来实现?

答:因为JDK动态代理生成的对象 默认是继承代理Proxy ,Java不支持多继承,所以JDK动态代理要基于接口来实现。

Q:JDK 动态代理中,目标对象调用自己的另一个方法,会经过代理对象吗?

答:不会,内部调用方法使用的对象是目标对象本身,被调用的方法不会经过代理对象。

Q:为什么不使用静态代理而使用动态代理?

静态代理是代理类在编译期间就创建好了,在编译时就已经将接口,被代理类,代理类等确定下来。如果有很多类很多接口需要代理,那么就只能使用代码提前写死,不够灵活;
使用了动态代理之后,不需要手动创建代理类,全部交给代理去完成对代理类的创建,实现无侵入式的代码扩展,这也是符合面向对象编程原则的操作。
在这里插入图片描述
在这里插入图片描述

2、CGLIB动态代理机制

在这里插入图片描述
在这里插入图片描述

3、JDK动态代理和CGLIB动态代理比较
  • JDK动态代理只能代理实现了接口的类或者直接代理接口。而CGLIB可以代理未实现任何接口的类。另外,CGLIB动态代理是通过生成—个被代理类的子类来拦截被代理类的方法调用,因此不能代理声明为finall类型的类和方法。
  • 就二者的效率来说,大部分情况都是JDK动态代理要更优秀,随着JDK版本的升级,这个优势更加明显。
4、静态代理和动态代理比较
  • 灵活性: 动态代理更加灵活,不需要必须实现接口,可以直接代理实现类,并且可以不需要针对每个目标类都创建一个代理类。另外,静态代理中,接口一旦新增加方法,目标对象和代理对象都要进行修改,这是非常麻烦的!
  • JVM层面: 静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的class文件。而动态代理是在运行时动态生成类字节码,并加载到JVM中的。

四、注解

1、何为注解?

注解是一种标记,使类或接口附加额外信息,帮助编译器和JVM完成一些特定功能,例如 @Override —— 标识一个方法是重写方法。
元注解 是自定义注解的注解,例如:
@Target : 约束作用位置;
@Rentention : 约束生命周期;
@Documented : 表明这个注解应该被 javadoc 记录。

注解生命周期有3大类,分别是:

  • RetentionPolicy.SOURCE:给编译器用的,不会写入class文件。
  • RetentionPolicy.CLASS:会写入class文件,在类加载阶段丢弃,也就是运行的时候就没这个信息了。
  • RetentionPolicy.RUNTIME:会写入class文件,永久保存,可以通过反射获取注解信息。
    在这里插入图片描述
Q:注解的解析方法有?

在这里插入图片描述

Copyright © 2010-2022 dgrt.cn 版权所有 |关于我们| 联系方式