Java内置注解:
- @Deprecated 意思是这个方法或类不再建议使用,可标注在构造方法、变量、局部变量、方法、参数、类型、包上;
- @Override 意思是重写父类的方法,标注在方法上;
- @SuppressWarnings 意思是抑制编译器产生警告信息,可标注在类、字段、方法、参数、构造方法,以及局部变量上
- 抑制单类型的警告:@SuppressWarnings("unchecked")
- 抑制多类型的警告:@SuppressWarnings(value={"unchecked", "rawtypes"})
- 抑制所有类型的警告:@SuppressWarnings("all")
- @SafeVarargs 用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误。一个方法使用@SafeVarargs注解的前提是,开发人员必须确保这个方法的实现中对泛型类型参数的处理不会引发类型安全问题,否则可能导致运行时的类型转换异常。
public static void main(String[] args) { List<String> list1 = Arrays.asList("one", "two"); List<String> list2 = Arrays.asList("three","four"); unsafeMethod(list1, list2); } @SafeVarargs // 其实并不安全! static void unsafeMethod(List<String>... stringLists) { Object[] array = stringLists; List<Integer> tmpList = Arrays.asList(42, 56); array[0] = tmpList; // tmpList是一个List对象(类型已经擦除),赋值给Object类型的对象是允许的(向上塑型),能够编译通过 String s = stringLists[0].get(0); // 运行时抛出ClassCastException! System.out.println(s); }
当代码执行到Object[] array = stringLists;时,数组array和stringLists同时指向了参数数组,tmpList是一个包含两个Integer对象的list对象。当执行到array[0] = tmpList时,参数数组stringLists的第0个元素指向了包含两个Integer对象的list对象tmpList,最后String s = stringLists[0].get(0);取出Integer对象赋给String时导致类型转换异常
- @FunctionalInterface
1、该注解只能标记在”有且仅有一个抽象方法”的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果符合”函数式接口”定义,加不加该注解没有影响。如果不是函数式接口,加上了@FunctionInterface,编译器会报错。
元注解:
- @Retention注解决定另一个注解的生命周期。有三种取值范围:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME,分别对应:Java源文件(.java文件)---->.class文件---->内存中的字节码
- @Target注解决定另一个注解可以加在类身上、属性身上或者方法上
- @Inherited 过Inherited元注解声明的自定义注解,在类上使用时,可以被子类继承
- @Documented 作用是能够将注解中的元素包含到 Javadoc 中去
- @Repeatable 是可重复的意思(Programmer会继承Hum上面标注的注解)
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Documented
@Retention(RetentionPolicy.RUNTIME) //运行时注解
@Target(ElementType.TYPE) //类上的注解
@Repeatable(Skills.class)
public @interface Skill {
String value() default "";
}
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Documented
@Retention(RUNTIME)
@Target(TYPE)
public @interface Skills {
Skill[] value();
}
@Skill(value="吃饭")
@Skill(value="睡觉")
public interface Human {
}
@Skill("编程")
@Skill("打游戏")
public class Programmer implements Human{
}
public static void main(String[] args) {
Human man = new Programmer();
Set<Class> classes=new HashSet<Class>();
classes.addAll(Arrays.asList(man.getClass().getInterfaces()));
classes.add(man.getClass());
for (Class<?> clazz : classes) {
Skill[] skills = clazz.getAnnotationsByType(Skill.class);
for (Skill skill : skills) {
System.out.println("他会:"+skill.value());
}
}
}