Java注解入门

简介: Java注解入门

1.注解的支持

Java从1.5开始使用注解,在1.5及更高的Java版本中都可以使用注解。

2.Java内置注解

Java在1.5中内置了三种标准注解,这三中注解分别为:

@Override:表示当前方法将会覆盖超类(父类)中的该方法。


@Deprecated:该注解表示,使用了该注解的方法是不被赞成使用的,在编译器中使用带有该注解的方法时将会出现提示(方法名称中间会有一个中划线)。


@SuppressWarnings:该注解会关闭编译器的不正当禁告。

3.编写注解要使用的注解——————元注解

Java专门提供了四种注解来让我们编写新的注解,这四个注解被称为元注解,这四种注解为:

@Documented:该注解表示新编写的注解是否包含在JavaDoc文档中,没有参数,添加该注解,在导出javadoc文档时回将该注解导出到javadoc文档中。


@Inherited:该注解表示本注解是否允许被它的子类所继承。


@Target:表示注解使用的地方,对注解进行使用限制,该注解有参数,参数的取值为ElementType的静态常量值,取值可以有多个,多个的写法为 @Target({ElementType.FIELD,ElementType.TYPE})格式。


  ElementType的静态常量值有:

    CONSTRUCTOR:构造器声明。

    FIELD:域的声明(包括 enum的实例)。

    LOCAL_VARIABLE:局部变声明。

    PACKAGE:包声明。

    PARAMETER:参数声明。

    TYPE:类、接口(包括注解类型)或enum声明。


@Retention:该注解表示此注解的保存级别,表示什么时候该注解将被抛弃,该注解有参数,参数的取值为RetentionPolicy的静态常量值,该注解不允许多取值,只允许有一个值。

  RetentionPolicy的静态常量值有:

  SOURCE:表示该注解只会在源代码文件中存在,编译成class文件时将被抛弃。

  CLASS:表示该注解在class文件中将存在,在加载到VM中时将被抛弃。

  RUNTIME:在VM中将保存该注解,在程序运行时可以通过反射的方式来获取注解的信息。

4.注解的编写方式:

注解的编写方式类似于接口的编写方式,只是要在interface关键字的前面加上@符号即可,然后在上方注解需要的元注解信息,


注解的参数编写方式:参数可以是单个,也可以有多个。也可以没有参数。如果一个参数需要同时有多个取值,则需要将该注解定义为数组的形式。声明参数时,参数后面必须要带有括号。示例如下:

@Documented@Inherited@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceController {
Stringvalue() default"";
String[] type() ;
    }

5.反射获取注解信息

如果注解的@Retention注解的取值为RetentionPolicy.RUNTIME,则在程序运行时可以通过反射的方式来获取注解的信息。


在项目运行时,我们可以使用类的全限定名(包名+"."+类名)来反射得到类对象。


然后通过类对象的isAnnotationPresent方法根据注解类的class来判断该类是否有特定的注解,如果有我们特定的注解,则可以通过类对象的getAnnotation方法根据注解类的class来获取该注解类的对象实例,然后使用注解类对象实例的参数来获取注解的参数值。

示例代码:

Class<?>clazz=Class.forName("com.jack.controller.CustomerController");//根据类的全限定名获取类对象。if(clazz.isAnnotation(Controller.class)){ //判断该类中是否有Controller注解。Controllercon=clazz.getAnnotation(Controller.class);//根据类的class来获取类的对象。Stringvalue=con.value();
String[] type=con.type();
  }

6.反射说明

在Java中可以通过反射的方法来获取Java的类对象和类对象中的属性以及方法。

第一步:根据类的全限定名(包名+"."+类名)来获取类的class对象。

Class<?>clazz=Class.forName("com.jack.controller.CustomerController");

第二步:根据类的class对象获取类的实例。

Objectobject=clazz.newInstance();

第三步:根据class对象获取类的构造方法。

// 1.获取该类的全部构造方法Constructor<?>[] constructor=object.getClass().getDeclaredConstructors();
//2.根据构造方法的参数类型来获取指定的构造方法。//获取空构造Constructor<?>constructor2=clazz.getDeclaredConstructor(); 
//获取只有一个String类型的参数的构造方法。Constructor<?>constructor2=clazz.getDeclaredConstructor(String.class);

第四步:根据class对象获取该类的方法。

//1.获取该类的全部方法Method[] methods=clazz.getDeclaredMethods();
//2.根据方法的名称和参数类型来获取指定的方法。//第一个参数为方法的名称,第二个参数为可变参数,接受方法的参数类型的class对象。Methodmethod=clazz.getDeclaredMethod("sayHello", null);

第五步:根据class对象获取类的成员变量。

//1.获取该类的所有成员变量Field[] fieldss=clazz.getDeclaredFields();
//2.根据成员变量的名称来获取指定的成员变量。Fieldfieldss=clazz.getDeclaredFields(变量名称);

第六步:类的实例化

使用第二步的方法实例化类的时候要求类必须要有一个无参构造方法,如果该类没有无参构造方法,则必须先根据class对象获取 该类的所有构造方法,或者获取特定的构造方法,然后使用构造方法来实例化该对象。

Constructor<?>constructor2=clazz.getDeclaredConstructor(String.class);
Objectobject=constructor2.newInstance(String类型的变量值);

第七步:给成员变量赋值。

获取到成员变量后可以给成员变量赋值。赋值使用成员变量Field的set方法来进行,set方法接受两个参数,第一个参数为该变量所在的类的对象,第二个参数为你要赋值的值,如果该成员变量时是私有的,那么在赋值之前必须要对该成员变量设置为支持赋值,该操作只需要设置该成员变量的setAccessible方法为true即可。

//1.获取类对象Objectobject=clazz.newInstance();
//2.根据成员变量名称获取指定的成员变量。Fieldfield=clazz.getDeclaredField(成员变量名称);
//3.设置成员变量可赋值field.setAccessible(true);
//4.给该成员变量赋值field.set(obj,要赋值给变量的值)

第八步:对象方法的调用。

通过class对象拿到该类所有的方法之后,可以通过调用方法的invoke方法来执行该方法,该方法有两个参数,第一个参数为该方法所在的类的对象,第二个参数为可变参数,接受该方法所需要的所有参数。

//1.获取类对象Objectobject=clazz.newInstance();
//2.根据方法名称和参数类型获取指定的方法Methodmethod=clazz.getDeclaredMethod("sayHello", String.class);
//3.调用该方法method.invoke(object,"hello");
相关文章
|
18天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
54 7
|
23天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
44 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
19天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
23天前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
63 5
|
1月前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
1月前
|
Java 开发者 Spring
[Java]自定义注解
本文介绍了Java中的四个元注解(@Target、@Retention、@Documented、@Inherited)及其使用方法,并详细讲解了自定义注解的定义和使用细节。文章还提到了Spring框架中的@AliasFor注解,通过示例帮助读者更好地理解和应用这些注解。文中强调了注解的生命周期、继承性和文档化特性,适合初学者和进阶开发者参考。
59 14
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
1月前
|
前端开发 Java
[Java]讲解@CallerSensitive注解
本文介绍了 `@CallerSensitive` 注解及其作用,通过 `Reflection.getCallerClass()` 方法返回调用方的 Class 对象。文章还详细解释了如何通过配置 VM Options 使自定义类被启动类加载器加载,以识别该注解。涉及的 VM Options 包括 `-Xbootclasspath`、`-Xbootclasspath/a` 和 `-Xbootclasspath/p`。最后,推荐了几篇关于 ClassLoader 的详细文章,供读者进一步学习。
37 12
|
1月前
|
存储 安全 Java
🌟Java零基础-反序列化:从入门到精通
【10月更文挑战第21天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
81 5
|
1月前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
36 1