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})
目录
相关文章
|
9天前
|
Java API 数据库
Java一分钟之-JPA注解:@Entity, @Table, @Id等
【6月更文挑战第14天】Java Persistence API (JPA) 是Java开发中的ORM框架,通过注解简化数据访问层。本文介绍了三个核心注解:`@Entity`标识实体类,`@Table`自定义表名,`@Id`定义主键。易错点包括忘记添加`@Entity`、未正确设置主键。建议使用`@GeneratedValue`和`@Column`细化主键策略和字段映射。正确理解和应用这些注解能提高开发效率和代码质量。
25 3
|
3天前
|
前端开发 Java 关系型数据库
JavaWeb开发简介
JavaWeb开发简介
12 0
|
1天前
|
存储 设计模式 Java
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
|
1天前
|
SQL 算法 安全
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
|
1天前
|
缓存 监控 Java
Java Socket编程最佳实践:优化客户端-服务器通信性能
【6月更文挑战第21天】Java Socket编程优化涉及识别性能瓶颈,如网络延迟和CPU计算。使用非阻塞I/O(NIO)和多路复用技术提升并发处理能力,减少线程上下文切换。缓存利用可减少I/O操作,异步I/O(AIO)进一步提高效率。持续监控系统性能是关键。通过实践这些策略,开发者能构建高效稳定的通信系统。
|
5天前
|
安全 Java 调度
Java Queue深度解析:LinkedList为何成为队列的最佳实践?
【6月更文挑战第18天】Java的`LinkedList`适合作为队列,因其双向链表结构支持O(1)的头尾操作。非线程安全的`LinkedList`在单线程环境下效率高,多线程时可通过`Collections.synchronizedList`封装。此外,它还可兼做栈和双端队列,提供任务调度的高效解决方案。
|
1天前
|
缓存 负载均衡 安全
Java并发编程实战--简介
Java并发编程实战--简介
6 0
|
1天前
|
安全 Java 开发工具
【Java并发基础】管程简介
【Java并发基础】管程简介
|
4天前
|
Java 大数据 API
|
8天前
|
安全 Java 程序员
[笔记] 疯狂JAVA讲义(第3版)第7章 Java基础类库
[笔记] 疯狂JAVA讲义(第3版)第7章 Java基础类库