注解随笔
注解:
注解的概述:
Java提供了一种源程序中元素和任何信息或者元数据相关联的一种方法 渠道。
源程序中的元素:java文件、构造方法、成员变量、成员方法...等。
信息:就是一些配置数据,也可以理解为是注释。
元数据:就是元注解,对注解进行注解。
关联:元素和注释绑定成为注解。
简单来说注解就是相当于一些类似于注释的信息和源程序中的元素绑定的一种技术,这就叫做注解。
这样可以通过反射获取到元素对象,在获取到这个元素上面绑定的注解,通过绑定的注解获取里面的配置信息,
从而达到能够在程序运行阶段通过这些信息动态的改变程序的运行逻辑。
注解的好处:
1、极大程度的简化了代码,提高了代码的可读性和扩展性。
2、能够配合反射将代码书写的更加的灵活,更加易于维护易于扩展,Properties配置,XML配置,注解配置[Java配置]
3、能够灵活的使用框架提供的注解,能够读懂框架源码。
JDK中常见的注解:
@Override: 表示注解修饰的方法必须满足重写的规则。
@Deprecated: 表示成员过时,编译器可以在程序运行的时候能获取到该注解。
@SupressWarnings: 表示忽略编译器的 警告。
@FunctionalInterface: 表示该接口是一个函数式接口,并且可以作为Lambda 表达式参数传入。
注解分类:
按照运行的机制进行分类:
1、源码注解注解只能在源码中有效,当编译生成字节码文件的时候,注解就不存在了,其实就是注释API。
2、编译时注解:注解在源码和编译时期有效,在jvm运行的时候就不存在了。
3、运行时注解:注解在源码和编译有效,同时在程序的执行过程也是存在的。
4、元注解:对注解进行注解。
按照来源来分类:
1、JDK中自带的注解:@Override,@Deprecated
2、第三方注解:@Table,@Column,@Component,@Service,@Bean
3、自定义注解:自己定义注解自己使用在自己的代码中
4、元注解:对注解进行注解的注解。
注解通过@interface 关键字进行定义(也就是创建注解)
public @interface DomeAnnotation {
}
它的形式跟接口很类似,不过前面多了一个 @ 符号。上面的代码就创建了一个名字为 DometAnnotaion 的注解。
注解的应用:
运用我们上面创建的注解方式如下:
@DomeAnnotation
public class Dome {
}
创建一个类 Dome,然后在类定义的地方加上 @DomeAnnotation 就可以用 DomeAnnotation 注解这个类了。
自定义注解的使用方式:
格式一: @注解的名称(属性名1=属性值1,属性名2=属性值2,属性名3=属性值3,...属性名n=属性值n)
注:有多少个属性就必须赋值多少个属性。
@DomeAnnotation(属性名=属性值,属性名2=属性值2...属性n=属性值n)
public class Dome {
}
格式二: @注解的名称(属性值)
注:适用于注解只有一个成员。
@DomeAnnotation(属性值)
public class Dome {
}
格式三: @注解的名称({属性值1,属性值2,属性值3,...属性值n})
注:适用于成员是数组的情况。
@DomeAnnotation(属性值1,属性值2...属性值n)
public class Dome {
}
格式四: @注解的名称
注:使用标记注解。
@DomeAnnotation
public class Dome {
}
元注解有五种,分别如下:
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD })
希望当前注解 XXX类名 可以用在类,接口,构造方法,方法上,指定了注解运用的地方。 @Retention(RetentionPolicy.RUNTIME)
希望当前注解 XXX类名 可以在运行时有效,应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
@Inherited
希望当前注解可以在子类中生效,用代码来解释
@Inherited
@Retention(RetentionPolicy.RUNTIME)
//Dome被@Inherited修饰
@interface Dome {
}
//Teacher类被Dome注解
@Dome
public class Teacher {
}
//Student类继承Teacher类也拥有了Dome这个注解
public class Student extends Teacher{
}
@Documented
希望当前注解可以在API文档中生成,它的作用是能够将注解中的元素包含到 Javadoc 中去。 @Repeatable ( )
可重复使用,也就是注解的值可以取多个值。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。
注解的属性:
1、注解只有成员变量,所以注解也叫成员变量,并且是没有方法的。
2、注解的成员变量在注解的定义中以 无参的方法 来声明,该方法名定义了该成员变量的名字,该返回值定义了该成员变量的类型。
3、在注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。
@Target({ ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface StudentAnnotation { //定义StudentAnnotation属性 String name(); int age(); String hobbys(); } //属性赋值 @StudentAnnotation(name="马大哈",age=21,hobbys="羽毛球") public class Student { }
注解中属性可以有默认值,默认值需要用 ”default “关键字指定 示例代码如下:
@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface StudentAnnotation {
//定义默认值
String name() default "马大哈";
int age() default 21;
String hobbys()default "羽毛球";
}
通过反射获取注解:
//通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
}
//通过 getAnnotations() 方法来获取
public Annotation[] getAnnotations() {
}
调用方法属性,代码示例如下:
@DomeAnnotation() public class Dome { public static void main(String[] args) { //通过反射获取注解 boolean hasAnnotation = Dome.class.isAnnotationPresent(DomeAnnotation.class); if ( hasAnnotation ) { DomeAnnotation da = Dome.class.getAnnotation(DomeAnnotation.class); System.out.println("name"+da.name()); System.out.println("age"+da.age()); System.out.println("hobbys"+da.hobbys()); } } }