Java注解介绍

JAVA注解

一、注解和注释区别:

1.1 注释:comment

给程序员看的,对程序做出解释。用于描述代码的作用和一些关键性的知识点,使用文字描述程序。

1.2 注解:annotation

  • JDK5.0后引入的新技术,他不是程序本身,但可以对程序做出解释。(这一点和注释没有区别)

  • 给程序员看,但主要目的是给程序看(多的这个“解”字)

二、注解详细定义

叫元数据,一种代码级别的说明,它是JDK1.5及以后版本引入的一个特性,与类、接口(注解本质上是一种特殊的接口)、枚举在同一个层次,它可以声明在包、类、字段、局部变量、方法参数等的前面,用来对这些元素进行说明、注释。很多框架的底层都是通过注解实现,比如spring boot,spring cloud。(框架的底层就是注解和反射)

2.1 注解的作用分类

编写文档:

通过代码里表示的元数据生成文档【生成doc文档】

代码分析:

通过代码里表示的元数据进行分析【使用反射】

编译检查:

通过代码里表示的元数据让编译器能够实现基本的编译检查【Override】

2.2 注解按照运行机制分类

源码注解:

注解只在源码中存在,编译成.class文件之后就不存在了。常见的注解为@Override,@SuppressWarnings

编译时注解:

注解在源码存在的基础上,也会在.class文件中存在,但是在运行阶段中就不存在了

这是默认的注解保留策略。这种策略下,注解将存在与.class文件,但是不能被运行时访问。通常这种注解策略用来处于一些字节码级别的操作。

运行时注解:

注解在运行阶段依然存在,且能够影响程序的运行过程,例如:@Autowired

通常情况下,我们都会结合反射来做一些事情。

2.3 注解的作用

  • 不是程序本身,可以对程序做出解释(这一点和注释一样)

  • 可以被其他程序(比如:编译器)读取,注解+反射。

  • 可以附加在package,class,method,field等上面,相当于给他们额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。

2.4 注解的格式

注解是以“@注解名”在代码中存在的;还可以添加一些参数值,例如:@suppressWarning(value=“unchecked”)

三、注解入门

分为内置注解和自定义注解

3.1 内置注解示例:

@Override:重写Object的toString()

@Override表示重写父类方法,在编译时存在

package com.happy;
//什么是注解
public class AnnotationStudy extends Object {
//@Override 重写的注解
@Override
public String toString() {
return super.toString();
}
public void testTread(){
Thread thread=new Thread();
}
}

@FunctionalInterface:Runnable接口用

线程接口Runnable的@FunctionalInterface,表示该接口是一个函数式编程接口(即只有一个待实现方法),不定义也没有影响程序执行。

package java.lang;
/**
* The <code>Runnable</code> interface should be implemented by any
* class whose instances are intended to be executed by a thread. The
* class must define a method of no arguments called <code>run</code>.
* <p>
* This interface is designed to provide a common protocol for objects that
* wish to execute code while they are active. For example,
* <code>Runnable</code> is implemented by class <code>Thread</code>.
* Being active simply means that a thread has been started and has not
* yet been stopped.
* <p>
* In addition, <code>Runnable</code> provides the means for a class to be
* active while not subclassing <code>Thread</code>. A class that implements
* <code>Runnable</code> can run without subclassing <code>Thread</code>
* by instantiating a <code>Thread</code> instance and passing itself in
* as the target. In most cases, the <code>Runnable</code> interface should
* be used if you are only planning to override the <code>run()</code>
* method and no other <code>Thread</code> methods.
* This is important because classes should not be subclassed
* unless the programmer intends on modifying or enhancing the fundamental
* behavior of the class.
*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since JDK1.0
*/
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}

destroy():Thread类的方法用@Deprecated

表示该方法废弃,在调用该方法时,IDE会以删除线标志该方法,不推荐程序员使用,但可以使用。

如下

@Deprecated
public void destroy() {
throw new NoSuchMethodError();
}
package com.happy;
//什么是注解
public class AnnotationStudy extends Object {
//@Override 重写的注解
@Override
public String toString() {
return super.toString();
}
public void testTread(){
Thread thread=new Thread();
thread.destroy();
}
}

@suppressWarnings

镇压警告,用来抑制编译时的警告信息,与前面的注释不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好的,我们选择性使用就好了。平时不建议镇压,

@SuppressWarnings("all")
@SuppressWarnings("unchecked")
@SuppressWarnings(value={"unchecked","deprecation"})
package java.lang;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
/**
* Indicates that the named compiler warnings should be suppressed in the
* annotated element (and in all program elements contained in the annotated
* element). Note that the set of warnings suppressed in a given element is
* a superset of the warnings suppressed in all containing elements. For
* example, if you annotate a class to suppress one warning and annotate a
* method to suppress another, both warnings will be suppressed in the method.
*
* <p>As a matter of style, programmers should always use this annotation
* on the most deeply nested element where it is effective. If you want to
* suppress a warning in a particular method, you should annotate that
* method rather than its class.
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* The set of warnings that are to be suppressed by the compiler in the
* annotated element. Duplicate names are permitted. The second and
* successive occurrences of a name are ignored. The presence of
* unrecognized warning names is <i>not</i> an error: Compilers must
* ignore any warning names they do not recognize. They are, however,
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
* <p> The string {@code "unchecked"} is used to suppress
* unchecked warnings. Compiler vendors should document the
* additional warning names they support in conjunction with this
* annotation type. They are encouraged to cooperate to ensure
* that the same names work across multiple compilers.
* @return the set of warnings to be suppressed
*/
String[] value();
}

注意:上面value()看似方法,实际为属性,而Sring为属性的类型,这是注解特殊的地方。

另外注意@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE) 这两个注解,为元注解,将在下面讲解。

加入镇压告警前:

加入压制后,idea不再暗黑提示

3.2 元注解

元注解的作用就是负责注解其他注解,就是解释其他注解的注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型做说明。也是内置注解。

这些类型和他们所支持的类在java.lang.annotation包中可以找到,分别是:

@Target:(重点)

用于描述注解的使用范围

(即:被描述的注解可以用在什么地方)

@Retention:(重点)

表示需要在什么级别保存该注释信息,用于描述注解的生命周期:SOURCE<CLASS<RUNTIME

一般我们使用定义为RUNTIME,即运行的时候依然存在有用,重点记忆。

例如:

Runtime定义的,将会在Runtime,Class和Source都存在和生效

而Class定义的,会在Class和Source生效

@Document:

说明该注解将包含在javadoc中

@Inherited:

说明子类可以继承父类中的该注解

测试元注解:

自定义注解,使用元注解,示例如下:

下图Target方法指定用在Method,固注解在类上时报错。

用数组引入多个Target范围后,不再报错

四、自定义注解

使用@ interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,注意前面有@,如果没有@就是普通接口

要点如下:

  • @interface用来声明一个注解,格式public @interface 注解名{定义内容}。

    如果是内部类方式申明注解,就省去public

  • 其中每一个方法实际上是声明了一个配置参数(或者理解为属性),方法的名称就是参数的名称。返回值的类型就是参数的类型

    返回值类型只能是基本类型、class、String、enum

  • 可以通过default类声明参数的默认值

  • 如果只有一个参数成员,一般为参数取名为value,使用时还可以起取消掉

  • 注解元素必须要有值,我们定义注解元素时,通常使用空字符串、0作为默认值

package com.happy;
import java.lang.annotation.*;
@MyAnnotation
public class MetaAnnotationUseStudy {
@MyAnnotation
public void test() {
}
// 注解可以显示赋值,如果没有默认值,我们必须显示赋值
@MyAnnotation2(name = "happytest",schools = {"哈佛"})
public void test2() {
}
}
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@interface MyAnnotation {
}
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
@Inherited
//作用范围为到运行时
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
// 注解的参数,注意这里不是方法
String name() default "";
int age() default 0;
int id() default -1;//如果默认值为-1,代表不存在
String[] schools() default {"北郵","清華"};
}

后面会介绍反射,注解必须+反射,才能读取注解里的东西,才能发挥最大功效,是框架的基础。

posted @   高兴518  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航