1.什么是注解?
从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。来源百度百科
1.1.为什么要使用注解呢?
1.让编码更简洁,代码更加清晰。
2.jdk自带的注解
1.@Override:覆盖实现父类的方法;
public interface Tea {
public String name();
}
public class BlackTea implements Tea {
@Override
public String name() {
// TODO Auto-generated method stub
return null;
}
}
2.@Deprecated:该方法已经过时
public interface Tea {
public String name();
@Deprecated
public BigDecimal price();
}
public class BlackTea implements Tea {
@Override
public String name() {
// TODO Auto-generated method stub
return null;
}
@Override
public BigDecimal price() {
// TODO Auto-generated method stub
return null;
}
}
public class Test {
public static void main(String[] args) {
Tea balckTea = new BlackTea();
balckTea.price();
}
}
3.@SuppressWarnings(“deprecation”):忽略警告,忽略掉@Deprecated的警告
public class Test {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Tea balckTea = new BlackTea();
balckTea.price();
}
}
4.@SafeVarargs 修饰引发该警告的方法或构造器
5.@FunctionalInterface 这个注解保证这个接口只有一个抽象方法,注意这个只能修饰接口
3.注解的分类
3.1.按运行机制分类
源码注解:注解在源码中存在,编译成.class文件就不存在了。
编译时注解:注解在源码和.class中都存在。
运行时注解:在运行阶段还会起作用,甚至会影响运行逻辑的注解。
3.2.元注解
//元注解:解释注解的注解
@Target({ElementType.METHOD,ElementType.TYPE}) //作用域,
@Retention(RetentionPolicy.RUNTIME) //生命周期 runtime source class
@Inherited //允许继承
@Documented //生成Doc包含注解
4.自定义注解
最简单的
public @interface TeaHouse {
}
4.2.自定义注解的一般格式
//元注解:解释注解的注解
@Target({ElementType.METHOD,ElementType.TYPE}) //作用域
@Retention(RetentionPolicy.RUNTIME) //生命周期 runtime source class
@Inherited //允许继承,接口继承没有作用,类继承的时候起作用
@Documented //生成Doc包含注解
// 如果注解只有一个成员,则成员名必须取名为value(),可以没有注解
// 使用@interface关键字定义注解
public @interface TeaHouse {
String name(); //成员变量以无參无异常方式声明,类型受限
int area() default 100; //可以以default为成员指定一个默认值
}
Target 作用域
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
使用自定义的注解
//通过注解初始化
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2,....>)
@TeaHouse (name="我是茶馆",area=100)
public String teaHouseName(){
return "tea";
}
5.解析注解
通过反射获取类、函数或成员上的 运行时注解信息,从而实现动态控制程序运行时逻辑。
- 使用类加载器加载类
- 找到类上面的注解
- 拿到注解实例
注解类
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface TeaHouse {
public String name();
public float area();
}
使用注解的类
@TeaHouse(area = 100, name = "红茶屋")
public class House {
}
测试类
package tech.yimocha.inter;
public class Test2 {
public static void main(String[] args) {
try {
Class c = Class.forName("tech.yimocha.inter.House");
boolean isHave = c.isAnnotationPresent(TeaHouse.class);
if (isHave) {
TeaHouse teaHouse = (TeaHouse) c.getAnnotation(TeaHouse.class);
System.out.println(teaHouse.name());
System.out.println(teaHouse.area());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}