1- 什么是注解
1.1 基本概念
用在类上,方法上,成员变量方法,构造器,…上对成分进行编译约束等操作的。注解是JDK1.5的新特性。
注解相当一种标记,是类的组成部分,可以给类携带一些额外的信息。注解是给编译器或JVM看的,编译器或JVM可以根据注解来完成对应的功能。
1.2 注解作用
- 不是程序本身 , 可以对程序作出解释(标记).方法重写约束 @Override
- 可以被其他程序(比如:编译器等)读取,现今最牛逼的框架技术多半都是在使用注解和反射。
1.3 Annotation的格式
注解是以"@注释名"在代码中存在的, 还可以添加一些参数值 , 例如:@SuppressWarnings(value=“unchecked”)
代码示例
public class AnnotationDemo01 {
}
@FunctionalInterface
interface Stu{
void test();
}
2-内置注解
@Override
定义在 java.lang.Override 中 , 此注释只适用于修辞方法 , 表示一个方法声明打算重写超类中的另一个方法声明。
@Deprecated
定义在java.lang.Deprecated中 , 此注释可以用于修辞方法 , 属性 , 类 。
表示不鼓励程序员使用这样的元素 , 通常是因为它很危险或者存在更好的选择 。
@SuppressWarnings
定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好了的,选择性的使用就好了。
2.1 代码示例
package cn.annotation_01;
import java.util.ArrayList;
import java.util.List;
public class Annotation01 extends Object{
// 1.重写的注解
@Override
public String toString() {
return super.toString();
}
// 2.方法过时了,不建议使用,可能存在问题,并不是不能使用!
@Deprecated
public static void test01(){
System.out.println("测试 @Deprecated");
}
//3. 发现 参数类型和参数名称,并不是方法!
@SuppressWarnings("all")
public void test02(){
List list = new ArrayList<>();
}
public static void main(String[] args) {
// 调用方法
test01();
}
}
3-元注解
3.1 基本概念
元注解是sun公司提供的,元注解是用在自定义注解上的注解。元注解是用来注解自定义注解的。
3.2 元注解类型
@Target
用于描述注解的使用范围(即:被描述的注解可以用在什么地方)。
@Retention
表示需要在什么级别保存该注释信息 , 用于描述注解的生命周期,(SOURCE < CLASS < RUNTIME)
@Document
说明该注解将被包含在javadoc中
@Inherited
说明子类可以继承父类中的该注解
3.3 代码示例
package cn.annotation_01;
import java.lang.annotation.*;
public class Annotation02 {
public void test(){
}
}
// 1.定义一个注解
// Target 表示注解可以用到什么地方
@Target(value = {
ElementType.METHOD, ElementType.TYPE})
// 2.Retention 注解在什么地方还有效
// runtime > class > sources
@Retention(value = RetentionPolicy.RUNTIME)
// 3.Deprecated 表示是否将注解生成在Javadoc中
@Deprecated
// 4.Inherited 子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
4-自定义注解
4.1 基本概念
使用 @interface自定义注解时 , 自动继承了java.lang.annotation.Annotation接口。
自定义注解的格式
[修饰符] @interface 注解名{
// 其中的每一个方法实际上是声明了一个配置参数。
}
参数类型
方法的名称就是参数的名称,返回值类型就是参数的类型 ( 返回值只能是基本类型,Class , String , enum )。
可以通过default来声明参数的默认值,如果只有一个参数成员 , 一般参数名为value。注解元素必须要有值 , 定义注解元素时 , 经常使用空字符串,0作为默认值 。
4.2 代码示例
package cn.annotation_01;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 自定义注解
*/
public class Test03 {
// 注解可以显示赋值,如果没有默认值,就必须给注解赋值
@MyAnnotation3(age = 26, name = "guardwhy")
public void test01(){
}
@MyAnnotation4("guardwhy")
public void test02(){
}
}
// 定义注解
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
// 注解的参数: 参数类型 + 参数名();
String name() default "";
int age();
// 如果默认值为-1,代表不存在.
int id() default -1;
String[] schools() default {
"计算机工程学院", "中山大学"};
}
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation4{
String value();
}
4.3 反射读取注解
代码示例
package cn.annotation_02;
import java.lang.annotation.*;
import java.lang.reflect.Field;
/*
* 学生类
*/
@Tablestu("db_student")
class Student{
// 成员属性
@Fieldstu(columnName="db_id", type = "int", length = 10)
private int id;
@Fieldstu(columnName="db_age", type = "int", length = 10)
private int age;
@Fieldstu(columnName = "db_name", type = "varchar", length = 6)
private String name;
public Student() {
}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
// 类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tablestu{
String value();
}
// 属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldstu{
String columnName();
String type();
int length();
}
public class Test01 {
public static void main(String[] args) throws Exception {
// 1.获得Class类对象
Class c1 = Class.forName("cn.annotation_02.Student");
// 2.通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation); // @cn.annotation_02.Tablestu(value=db_student)
}
// 3.获得注解的value的值
Tablestu tablestu = (Tablestu)c1.getAnnotation(Tablestu.class);
String value = tablestu.value();
System.out.println(value); // db_student
// 4.获得类指定的注解
Field f = c1.getDeclaredField("id");
Fieldstu annotation = f.getDeclaredAnnotation(Fieldstu.class);
System.out.println(annotation.columnName()); // db_id
System.out.println(annotation.type()); // int
System.out.println(annotation.length()); // 10
}
}