概述
①Java的注解又称标注,它是程序的元数据,也是程序代码的标记,主要添加到程序代码上,作说明和解释。元数据是用来描述数据的一种数据。
②Java中的注解可用于类、构造方法、成员变量、方法、参数等的声明中,注解功能不影响程序正常运行,但是对编译器等辅助工具造成影响。
③注解可以在编译、加载类和运导,可以根据注解对数据进行相应的处理。
- 使用反射功能,可以对程序代码进行分析;
- 使用系统定主解,可以在编译时对程序进行检查;
- 使用元注解,可以生成相应的文档。
④注解用在包、类、字段、方法、局部变量、方法参数等的前面,对这些元素进行说明和注释。注解可以自定义,也可以使用系统的注解。
系统注解
1、@Override
- 用来修饰一个方法,这个方法必须是对父类中的方法的重写。如果一个方法没有重写父类中的方法,在使用这个注解时编译器将提示错误。被@Override注解的方法必须在父类中有同样的方法,编译才会通过。
- 在子类中重写父类或接口的方法时,@Override并不是必须加上的,但是建议使用这个注解。在某些情况下,若修改了父类方法的名字,那么子类的方法将不再属于重写。由于没有@Override,编译器不会发现问题;但是如果有@Override,编译器就会检查注解的方法是否覆盖了父类的方法。
//步骤一:创建父类
public class Super {
public void Method(){
System.out.println("父类方法");
}
}
//步骤二:创建子类
public class Sub {
public void method(){
System.out.println("子类方法");
}
}
//步骤三:创建测试类
public class Test {
public static void main(String[] args){
Super sover = new Sub();
sover.Method(); //由于多态存在,调用的是父类的Method(),父类的Method()没有被子类重写
}
}
//使用@Override修饰子类的method(),表示这个方法是重写父类的方法
public class Sub {
@Override
public void Method(){ //由于在父类找不到这个方法,会报错,应改成同名的Method()
System.out.println("子类方法");
}
}
2、@Deprecated
@Deprecated可以用来注解不再使用已经过时的类、方法和属性。如果代码使用了@Deprecated注解的类、方法和属性,编译器会给出警告。
当使用@Deprecated注解时,建议使用对应的@deprecated JavaDoc符号说明这个类、方法或属性过时的原因以及它的替代方案。
@Deprecated
/*
@deprecated 这个类存在缺陷,使用新的NewDeprecatedTest类替代它
*/
public class DeprecatedTest{
…//类体
}
3、@SuppressWarnings
@Suppress Warnings用来抑制编译器生成警告信息。它修饰的元素为类、方法、方法参数、属性和局变量。当一个方法调用了过时的方法或者进行不安全的类型转换时,编译器会生成警告,此时可以为这方法增加@SuppressWarnings注解,从而抑制编译器生成警告。该注解遵循就近原则。
import java.util.ArrayList;
import java.util.List;
public class SuppressWarningsExample {
@SuppressWarnings("unchecked") // 抑制未检查的类型转换警告
public static void main(String[] args) {
List rawList = new ArrayList(); // 原始类型的使用
rawList.add("Hello");
rawList.add("World");
// 这里的 cast 会产生警告,但我们用 @SuppressWarnings 抑制它
List<String> stringList = (List<String>) rawList;
for (String s : stringList) {
System.out.println(s);
}
}
}
自定义注解
在定义自定义注解时,不可以继承其他的注解或接口。@interface只用来声明一个注解,注解中的方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。返回值的类型只能是基本类型、Class、String、Enum。可以通过default关键字声明参数的默认值。
[public | final] @interface 注解名
{数据类型 注解元素名() [default 默认值];//注解元素
}
- 其中,关键字@interface表示声明一个自定义注解,“注解名”是合法的标识符。“注解元素”是无参数的方法,方法的类型表示注解元素的类型。
- 如果只有一个注解元素,在注解元素名为value的情况下,在使用的时候就可以不写出注解元素名,出注解值即可。
- 在使用目定义注解时,要将自定义注解放在需要注解的前一行或者同一行,并在自定义注解后的括号中写出注解元素的值。如果使用默认值,则可以不给出注解值。如果只有一个注解元素并且名位value,只需要给出值,不需要给出注解元素名。
注解元素的值
注解元素一定要有确定的值,可以在定义注解时指定它的默认值,也可以在使用注解时指定默认值,非基本类型的注解元素的值不能为null。因此,经常使用空字符串或0作为默认值。
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.METHOD) // 注解可以应用于方法
public @interface MyCustomAnnotation {
String value() default "default value";
}
//使用自定义注解
public class MyClass {
@MyCustomAnnotation(value = "Hello, Custom Annotation!")
public void myAnnotatedMethod() {
System.out.println("Executing myAnnotatedMethod.");
}
}
//反射获取注解信息
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) {
try {
MyClass myClass = new MyClass();
Method method = myClass.getClass().getMethod("myAnnotatedMethod");
// 检查方法是否有自定义注解
if (method.isAnnotationPresent(MyCustomAnnotation.class)) {
MyCustomAnnotation annotation = method.getAnnotation(MyCustomAnnotation.class);
System.out.println("Annotation value: " + annotation.value());
}
myClass.myAnnotatedMethod(); // 执行方法
} catch (Exception e) {
e.printStackTrace();
}
}
}
元注解
Java 5.0 API的 java.lang.annotation 包中提供了4个标准的元注解类型,即@Target、@Retention、aDocumented和@Inherited。它们的作用是对其他注解类型进行注解。
1、@Target
@Targett指定注解类型所作用的程序元素的种类。若注解类型声明中不存在Target元注解,则声明型可以用在任一程序元素上;若存在元注解,则编译器强制实施指定的类型限制。
@Target的取值是枚举类ElementType的成员(称为枚举常量)。
2、@Retention
@Retention的作用是指定需要在说明级别保留该注解信息,用于描述注解的声明周期,它取值是枚举类RetentionPolicy的成员。
3、@Docuriented
@Documented指示某一类型的注解将通过javadoc和类似的默认工具进行文档化。
4、@lnherited
继承是Java的一大特征,在类中除了private的成员以外都会被子类继承。默认情况下,父类注解是不会被子类继承的,只有使用元注解@Inherited的注解才可以被子类继承。
多重注解
在注解前使用@Repeatable允许同一类型的注解多次使用。