关于java注解
学习注解的目的:
- 读懂别人代码,特别是框架代码
- 让编程更加简洁,代码更清晰
概念:
- 也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
JDK当中的注解:
- @override
- @Deprecated
- @Suppvisewarnings
public interface Person {
public String name();
public int age();
//@Deprecated
//它的作用是对不应该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息,
//它与javadoc里的@deprecated标记有相同的功能,准确的说,
//它还不如javadoc @deprecated,因为它不支持参数
@Deprecated
public void Sing();
}
public class Child implements Person{
//@Override
//它的作用是对覆盖超类中方法的方法进行标记,
//如果被标记的方法并没有实际覆盖超类中的方法,则编译器会发出错误警告。
@Override
public String name() {
return null;
}
@Override
public int age() {
return 0;
}
@Override
public void Sing() {
}
}
public class Test {
// 其参数有:
// deprecation,使用了过时的类或方法时的警告
// unchecked,执行了未检查的转换时的警告
// fallthrough,当 switch 程序块直接通往下一种情况而没有 break 时的警告
// path,在类路径、源文件路径等中有不存在的路径时的警告
// serial,当在可序列化的类上缺少serialVersionUID 定义时的警告
// finally ,任何 finally子句不能正常完成时的警告
// all,关于以上所有情况的警告
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Person p = new Child();
p.Sing();
}
}
注解分类:
按运行机制来分:
- 源码注解:注解只在源码中存在,编译成.class文件就不存在了
- 编译时注解:注解在源码和.class文件存在(@override)
- 运行时注解:在运行阶段起作用
按来源分:
- 来自JDK的注解
- 来自第三方的注解
- 自定义的注解
自定义注解
语法要求:
- 它类似于新创建一个接口文件,但为了区分,我们需要将它声明为
@interface
元注解:
。。 | 。。 |
---|---|
@Target({ElementType.METHOD,ElementType.TYPE}) //注解的作用域//注解的作用域列表 | CONSTRUCTOR(构造函数声明) |
LOCAL_VARIABLE(局部变量声明) | |
PACKGE(包声明) | |
PARAMETER(参数声明) | |
TYPE(类接口) | |
@Retention(RetentionPolicy.RUNTIME)//生命周期 | |
CLASS:编译时会记录到class中,运行时忽略。 | |
RUNTIME:运行时存在,可通过反射读取 | |
@Inherited//标示性的元注解,表示允许子类继承 | |
@Documented//生成Javadoc时会包含注解信息 |
使用自定义注解:
使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,…)
@Description(desc ="I am eyeColor",author="C boy",age=18)
public String eyeColor(){
return "red";
}
自定义注解:
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;
/**
* 使用@interface关键字定义注解
* 1.成员类型是受限的合法类型包括基本类型及String,Class.Annotation,Enumeraion
* 2.如果只有一个成员成员名必须取名为value,在使用时可以忽略成员名和赋值号(=)
* 3.注解类可以没有成员,没有成员的注解称为标识注解
*/
@Target({ ElementType.METHOD, ElementType.TYPE })//注解作用域
@Retention(RetentionPolicy.RUNTIME)//生命周期
@Inherited//允许子类
@Documented//生成javadoc时会包含注解
public @interface Description {
// 成员以无参,无异常方式声明
String desc();
String author();
// 可以用defalut为成员指定一个默认值
int age() default 18;
}
解析注解:
import java.lang.reflect.Method;
public class TestAnn {
public static void main(String[] args) {
try {
// 使用类加载器加载类
Class c = Class.forName("annotation.Dog");
// 2.找到类的注解
boolean isExit = c.isAnnotationPresent(Description.class);
// 3.获取类
if (isExit) {
// 拿到注解实例
Description d = (Description) c.getAnnotation(Description.class);
System.out.println(d.value());
}
// 找到方法的注解
Method[] methods = c.getMethods();
for (Method method : methods) {
boolean ismethod = method.isAnnotationPresent(Description.class);
if (ismethod) {
Description d = (Description) method.getAnnotation(Description.class);
System.out.println(d.value());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}