一文读懂Java注解

什么是注解

Java官方文档上说,注解是元数据的一种形式,它提供不属于程序一部分的数据,注解对被注解的代码没有直接的影响。

准确上说,注解只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。

主要用途

注解有很多种中途,其中包括:

  • 提供编译器使用信息

编译器可以使用这些注解来检查错误或者禁止显示告警,如@Override**、@Deprecated@SuppressWarnings

  • 编译或部署时处理

可以通过注解信息生产相关代码,如lombok的**@Data**、@ToString等注解

  • 运行时处理

在运行时处理的逻辑,如常用的Spring框架中的**@Service**、@Component@SpringBootApplication等注解

Java 内置的注解

Java一开始有定义了一套注解,共8个,3个在java.lang中,剩下4个在java.lang.annotation中

其中,作用于代码的注解有

  • @Override - 检查该方法是否是重载方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

作用在其他注解的注解(或者说是元注解)有

  • @Retention - 注解的声明周期,标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

    value为RetentionPolicy类型,有以下三种

    • RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
    • RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
    • RetentionPolicy.RUNTIME:永久保存,可以反射获取
  • @Target - 注解的作用目标,标记这个注解应该是哪种 Java 成员。

    value为ElementType数组,ElementType类型如下

    • ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
    • ElementType.FIELD:允许作用在属性字段上
    • ElementType.METHOD:允许作用在方法上
    • ElementType.PARAMETER:允许作用在方法参数上
    • ElementType.CONSTRUCTOR:允许作用在构造器上
    • ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
    • ElementType.ANNOTATION_TYPE:允许作用在注解上
    • ElementType.PACKAGE:允许作用在包上
  • @Inherited - 阐述了某个被标注的类型是被继承的。

  • @Documented - 标记这些注解是否包含在用户文档中。

从java7开始,又额外添加了3个注解

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

自定义注解

自定义注解,是使用注解元数据来实现的,和java内置注解一样,是使用**@interface**关键字来声明的。

定义注解格式

public @interface 注解名 {定义体}

如:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DemoAnnotation {
  	String value(); //public 关键字可以去掉,默认是public的
    String name() default "write"; 
}

参数只有public或默认(default)这两个访问修饰符,例如 String value() 这里把方法设为 default 类型

注解参数可支持的数据类型有:

  • 所有基本数据类型(int,float,boolean,byte,double,char,long,short)

  • String类型

  • Class类型

  • enum类型

  • Annotation类型

  • 以上所有类型的数组

其中当value属性存在的时候,且只写value属性是,可以省略value,如spring的**@Component**注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    String value() default "";
}

使用的时候可以是 @Component、@Component(“jfound”)、@Component(value=“jfound”);

注解与反射

通过过反射是可以获取相应的注解的,然后获取注解后根据注解或者注解里面的属性来进一步逻辑处理。

如Class类中提供了一下一些方法用于反射注解:

  • getAnnotation:返回指定的注解
  • isAnnotationPresent:判定当前元素是否被指定注解修饰
  • getAnnotations:返回所有的注解
  • getDeclaredAnnotation:返回本元素的指定注解
  • getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的

相应的,Field、Method等类也有同样的方法来反射注解

注解使用案例

  • 定义注解
package jfound;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface CustomName {
    String value();
}
  • 定义实体类
package jfound;

@CustomName("person")
public class Person {
    @CustomName("user_name")
    private String userName;
    @CustomName("gender")
    private String sex;
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserName() {
        return userName;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getSex() {
        return sex;
    }
}
  • 反射使用
package jfound;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class AnnotationDemo {
    public static void main(String[] args) throws Exception {
        Person person = new Person();
        person.setUserName("JFound");
        person.setSex("boy");
        
        String personKeyName = "";
        CustomName annotation = Person.class.getAnnotation(CustomName.class);
        if (annotation != null) {
            personKeyName = annotation.value();
        }
        Map<String, Object> data = new HashMap<>();
        for (Field field : Person.class.getDeclaredFields()) {
            CustomName fieldAnnotation = field.getAnnotation(CustomName.class);
            String key;
            if (fieldAnnotation == null) {
                key = field.getName();
            } else {
                key = fieldAnnotation.value();
            }
            field.setAccessible(true);
            Object value = field.get(person);
            data.put(key, value);
        }

        System.out.println("person key name:" + personKeyName);
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());
        }
    }
}

输出

person key name:person
key:gender value:boy
key:user_name value:JFound

上面的例子至少个简单的注解使用,注解使用的场景还是比较多的,如一开始的用途例子中的lombok用于代码生成,spring中的@Component用于bean的生产,jpa中的@Table 用于数据表的识别等等。

总结

  • java使用**@interface**来定义注解
  • 注解可以定义两个或多个参数和默认值,核心参数使用value名称
  • 应当设置**@Retention(RetentionPolicy.RUNTIME)**便于运行期读取该Annotation。
  • 注解是可以通过反射来使用的

在这里插入图片描述

基于TROPOMI高光谱遥感仪器获取的大气成分观测资料,本研究聚焦于大气污染物一氧化氮(NO₂)的空间分布与浓度定量反演问题。NO₂作为影响空气质量的关键指标,其精确监测对环境保护与大气科学研究具有显著价值。当前,利用卫星遥感数据结合先进算法实现NO₂浓度的高精度反演已成为该领域的重要研究方向。 本研究构建了一套以深度学习为核心的技术框架,整合了来自TROPOMI仪器的光谱辐射信息、观测几何参数以及辅助气象数据,形成多维度特征数据集。该数据集充分融合了不同来源的观测信息,为深入解析大气中NO₂的时空变化规律提供了数据基础,有助于提升反演模型的准确性与环境预测的可靠性。 在模型架构方面,项目设计了一种多分支神经网络,用于分别处理光谱特征与气象特征等多模态数据。各分支通过独立学习提取代表性特征,并在深层网络中进行特征融合,从而综合利用不同数据的互补信息,显著提高了NO₂浓度反演的整体精度。这种多源信息融合策略有效增强了模型对复杂大气环境的表征能力。 研究过程涵盖了系统的数据处理流程。前期预处理包括辐射定标、噪声抑制及数据标准化等步骤,以保障输入特征的质量与一致性;后期处理则涉及模型输出的物理量转换与结果验证,确保反演结果符合实际大气浓度范围,提升数据的实用价值。 此外,本研究进一步对不同功能区域(如城市建成区、工业带、郊区及自然背景区)的NO₂浓度分布进行了对比分析,揭示了人类活动与污染物空间格局的关联性。相关结论可为区域环境规划、污染管控政策的制定提供科学依据,助力大气环境治理与公共健康保护。 综上所述,本研究通过融合TROPOMI高光谱数据与多模态特征深度学习技术,发展了一套高效、准确的大气NO₂浓度遥感反演方法,不仅提升了卫星大气监测的技术水平,也为环境管理与决策支持提供了重要的技术工具。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值