Java基础16-Java注解简介和最佳实践(二)

简介: Java基础16-Java注解简介和最佳实践(二)


Java基础16-Java注解简介和最佳实践(一):https://developer.aliyun.com/article/1535695

变量注解

下面是一个变量注解的例子:

public class TheClass {  @MyAnnotation(name="someName",  value = "Hello World")  public String myField = null;}

你可以像这样来访问变量的注解:

Field field = ... //获取方法对象</pre><pre>Annotation[] annotations = field.getDeclaredAnnotations();for(Annotation annotation : annotations){ if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }}

你可以像这样访问指定的变量注解:

Field field = ...//获取方法对象</pre><pre>Annotation annotation = field.getAnnotation(MyAnnotation.class);if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value());}

Java注解相关面试题

什么是注解?他们的典型用例是什么?

注解是绑定到程序源代码元素的元数据,对运行代码的操作没有影响。

他们的典型用例是:

  • 编译器的信息 - 使用注解,编译器可以检测错误或抑制警告
  • 编译时和部署时处理 - 软件工具可以处理注解并生成代码,配置文件等。
  • 运行时处理 - 可以在运行时检查注解以自定义程序的行为

描述标准库中一些有用的注解。

java.lang和java.lang.annotation包中有几个注解,更常见的包括但不限于此:

  • @Override -标记方法是否覆盖超类中声明的元素。如果它无法正确覆盖该方法,编译器将发出错误
  • @Deprecated - 表示该元素已弃用且不应使用。如果程序使用标有此批注的方法,类或字段,编译器将发出警告
  • @SuppressWarnings - 告诉编译器禁止特定警告。在与泛型出现之前编写的遗留代码接口时最常用的
  • @FunctionalInterface - 在Java 8中引入,表明类型声明是一个功能接口,可以使用Lambda Expression提供其实现

可以从注解方法声明返回哪些对象类型?

返回类型必须是基本类型,String,Class,Enum或数组类型之一。否则,编译器将抛出错误。

这是一个成功遵循此原则的示例代码:

enum Complexity {    LOW, HIGH}public @interface ComplexAnnotation {    Class<? extends Object> value();    int[] types();    Complexity complexity();}

下一个示例将无法编译,因为Object不是有效的返回类型:

public @interface FailingAnnotation {    Object complexity();}

哪些程序元素可以注解?

注解可以应用于整个源代码的多个位置。它们可以应用于类,构造函数和字段的声明:

@SimpleAnnotationpublic class Apply {    @SimpleAnnotation    private String aField;    @SimpleAnnotation    public Apply() {        // ...    }}

方法及其参数:

@SimpleAnnotationpublic void aMethod(@SimpleAnnotation String param) {    // ...}

局部变量,包括循环和资源变量:

@SimpleAnnotationint i = 10;for (@SimpleAnnotation int j = 0; j < i; j++) {    // ...}try (@SimpleAnnotation FileWriter writer = getWriter()) {    // ...} catch (Exception ex) {    // ...}

其他注解类型:

@SimpleAnnotationpublic @interface ComplexAnnotation {    // ...}

甚至包,通过package-info.java文件:

@PackageAnnotationpackage com.baeldung.interview.annotations;

从Java 8开始,它们也可以应用于类型的使用。为此,注解必须指定值为ElementType.USE的@Target注解:

@Target(ElementType.TYPE_USE)public @interface SimpleAnnotation {    // ...}

现在,注解可以应用于类实例创建:

new @SimpleAnnotation Apply();

类型转换:

aString = (@SimpleAnnotation String) something;

接口中:

public class SimpleList<T>  implements @SimpleAnnotation List<@SimpleAnnotation T> {    // ...}

抛出异常上:

void aMethod() throws @SimpleAnnotation Exception {    // ...}

有没有办法限制可以应用注解的元素?

有,@ Target注解可用于此目的。如果我们尝试在不适用的上下文中使用注解,编译器将发出错误。

以下是仅将@SimpleAnnotation批注的用法限制为字段声明的示例:

@Target(ElementType.FIELD)public @interface SimpleAnnotation {    // ...}

如果我们想让它适用于更多的上下文,我们可以传递多个常量:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })

我们甚至可以制作一个注解,因此它不能用于注解任何东西。当声明的类型仅用作复杂注解中的成员类型时,这可能会派上用场:

@Target({})public @interface NoTargetAnnotation {    // ...}

什么是元注解?

元注解适用于其他注解的注解。

所有未使用@Target标记或使用它标记但包含ANNOTATION_TYPE常量的注解也是元注解:

@Target(ElementType.ANNOTATION_TYPE)public @interface SimpleAnnotation {    // ...}

下面的代码会编译吗?

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })public @interface TestAnnotation {    int[] value() default {};}

不能。如果在@Target注解中多次出现相同的枚举常量,那么这是一个编译时错误。

删除重复常量将使代码成功编译:

@Target({ ElementType.FIELD, ElementType.TYPE})
目录
相关文章
|
3月前
|
存储 Java 程序员
Java 基础知识点全面梳理包含核心要点及难点解析 Java 基础知识点
本文档系统梳理了Java基础知识点,涵盖核心特性、语法基础、面向对象编程、数组字符串、集合框架、异常处理及应用实例,帮助初学者全面掌握Java入门知识,提升编程实践能力。附示例代码下载链接。
129 0
|
3月前
|
人工智能 安全 Java
Go与Java泛型原理简介
本文介绍了Go与Java泛型的实现原理。Go通过单态化为不同类型生成函数副本,提升运行效率;而Java则采用类型擦除,将泛型转为Object类型处理,保持兼容性但牺牲部分类型安全。两种机制各有优劣,适用于不同场景。
95 24
|
3月前
|
人工智能 Java
java中static关键字简介
`static`关键字用于修饰类的成员变量和方法,使其属于类而非对象。静态成员可通过类名直接访问,无需实例化对象。静态方法只能访问静态成员,不能直接访问非静态成员或使用`this`关键字。此外,静态代码块在类首次加载时执行且仅执行一次,适用于初始化操作。
120 0
|
4月前
|
存储 安全 Java
2025 年最新 40 个 Java 基础核心知识点全面梳理一文掌握 Java 基础关键概念
本文系统梳理了Java编程的40个核心知识点,涵盖基础语法、面向对象、集合框架、异常处理、多线程、IO流、反射机制等关键领域。重点包括:JVM运行原理、基本数据类型、封装/继承/多态三大特性、集合类对比(ArrayList vs LinkedList、HashMap vs TreeMap)、异常分类及处理方式、线程创建与同步机制、IO流体系结构以及反射的应用场景。这些基础知识是Java开发的根基,掌握后能为后续框架学习和项目开发奠定坚实基础。文中还提供了代码资源获取方式,方便读者进一步实践学习。
853 2
|
4月前
|
Java 测试技术 API
现代化 java 分层开发实施策略与最佳实践指南
现代化Java分层开发采用清晰的多层架构,包括Controller、Service、Repository和DTO等核心层次。文章详细介绍了标准Maven/Gradle项目结构,各层职责与实现规范:实体层使用JPA注解,DTO层隔离数据传输,Repository继承JpaRepository,Service层处理业务逻辑,Controller层处理HTTP请求。推荐使用Spring Boot、Lombok、MapStruct等技术栈,并强调了单元测试和集成测试的重要性。这种分层设计提高了代码的可维护性、可测试
131 1
|
4月前
|
存储 安全 Java
Java 基础知识面试题汇总 最全面的 Java 基础面试题整理
本文全面解析Java基础知识面试题,涵盖Java基础概念、面向对象编程、异常处理、集合框架等核心内容。通过实际应用场景,提供技术方案与应用实例,如JDK与JRE区别、==与equals()差异、String类特性、final与static关键字用法、多继承替代方案及接口与抽象类对比。帮助开发者夯实基础,高效备考,提升实战能力。附带完整代码示例,可供下载学习。
546 3
|
4月前
|
存储 监控 Java
Java内存管理集合框架篇最佳实践技巧
本文深入探讨Java 17+时代集合框架的内存管理最佳实践,涵盖不可变集合、Stream API结合、并行处理等现代特性。通过实战案例展示大数据集优化效果,如分批处理与内存映射文件的应用。同时介绍VisualVM、jcmd等内存分析工具的使用方法,总结六大集合内存优化原则,助你打造高性能Java应用。附代码资源链接供参考。
118 3
|
5月前
|
IDE Java 开发工具
【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤
IntelliJ IDEA创建Java项目的图文详细步骤,手把手带你创建Java项目
722 10
【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤
|
7月前
|
存储 设计模式 Java
重学Java基础篇—ThreadLocal深度解析与最佳实践
ThreadLocal 是一种实现线程隔离的机制,为每个线程创建独立变量副本,适用于数据库连接管理、用户会话信息存储等场景。
221 5
|
7月前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
238 0