12 注解与反射

12.1 注解

  • 注解(Annotation)也被称为元数据(Metadata),用于修饰包、方法、属性、构造器、局部变量等数据信息。
  • 注解不影响程序逻辑,但注解可以被编译或运行。
  • JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。

常见注解:

  • @Override: 限定某个函数必须重写(覆盖)基类的函数,该注解只能用于函数
  • @Deprecated:用于表示某个程序元素(类、函数)已过时
  • @SuppressWarnings:抑制编译器警告

元注解:

修饰其他注解的注解,就被称为元注解。

  • Retention:指定注解的作用范围,运用周期、阶段;

    • SOURCE
    • RUNTIME
  • Target:指定注解可以用在哪些地方,比如方法,类等

  • Document:注定注解是否出出现在javadoc中

  • Inherited:子类会继承父类的注解

12.2 反射

解释型语言:走一步看一步,可以边执行边写,但效率比较低。

针对if-else分支:

  • 非解释型语言代码的每一个分支都会被检测;
  • 解释型语言只检测会走到的分支,另一个分支的报错信息可能不会被找出。

Java在两者之间,不是完全编译完再执行,也不是边编译边执行。

  • 先将源文件编译成中间代码——Java字节码;
  • Java虚拟机先加载类;
  • Java虚拟机执行Java字节码。

假设现在有一个很大的项目,我们想要修改其中很小的一段代码:

  • C++无论修改多少,都需要全局重新编译;
  • Python很简单;
  • 而Java就用到了反射机制。(将修改后的逻辑加到原项目中,不需要重新编译整个项目)

反射:动态引入类、动态调用实例的成员函数、成员变量等。

常用API:

  • java.lang.Class
  • java.lang.reflect.Method
  • java.lang.reflect.Field
  • java.lang.reflect.Constructor

举例:

package org.yxc.thirdparty;

public class Calculator {
    public String name;

    public Calculator() {}

    public Calculator(String name) {
        this.name = name;
    }

    public int add(int a, int b) {
        return a + b;
    }
}
package org.yxc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> cls = Class.forName("org.yxc.thirdparty.Calculator");
        Object o = cls.newInstance();//调用无参构造函数

        Method method = cls.getMethod("add", int.class, int.class);
        int res = (int)method.invoke(o, 3, 4);//执行函数
        System.out.println(res);

        Field field = cls.getField("name");
        field.set(o, "My Calculator!");
        System.out.println(field.get(o));

        //有参构造函数
        Constructor<?> constructor = cls.getConstructor(String.class);
        Object new_o = constructor.newInstance("New Calculator!");
        System.out.println(new_o);
    }
}

优缺点:

  • 优点:可以动态创建和使用对象,使用灵活
  • 缺点:执行速度慢
posted @ 2023-03-19 17:00  杨大康  阅读(24)  评论(0)    收藏  举报