3.3 元注解
元注解就是可以注解到注解上的注解,也可以理解为元注解是一种基本注解,但是它可以运用到其他注解上。
元注解有:@Target,@Retention,@Documented,@Inherited,@Repeatable 5种
(1)@Target:target是目标的意思,@Target指定注解可以运用的地方。他的取值如下:
例:@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
ElementType.TYPE给一个类型进行注解,比如类、接口、枚举ElementType.FIELD可以给属性进行注解ElementType.METHOD可以给方法进行注解ElementType.PARAMETER 可以给一个方法内的参数进行注解ElementType.CONSTRUCTOR可以给构造方法进行注解ElementType.LOCAL_VARIABLE可以给局部变量进行注解
ElementType.ANNOTATION_TYPE
可以给一个注解进行注解ElementType.PACKAGE可以给一个包进行注解
(2)@Retention:retention的意思为保留,@Retention指定注解的存活时间,他的取值如下
|
例:@Retention(RetentionPolicy.SOURCE)
|
|
RetentionPolicy.SOURCE
|
注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
|
|
RetentionPolicy.CLASS
|
注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
|
|
RetentionPolicy.RUNTIME
|
注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
|
(3)@Documented:他的作用是能够将注解中的元素包含到 Javadoc 中去。
(4)@Inherited:Inherited的意思为继承。他的作用是:如果一个超类被一个被@Inherited注解注解过的注解进行注解的话,如果子类没有被任何注解应用,子类就继承了超类的注解。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Inherit {}
@Inherit
public class A {}
public class B extends A {}
//注解Inherit被@Inherited 修饰,之后类A被Inherit注解,类B继承A,类B也拥有Inherit这个注解。
(5)@Repeatable:repeatable是可重复的意思,jdk1.8才加进来的。在需要对同一种注解多次使用时,往往需要借助@Repeatable。比如人有多中身份把身份当成注解
//先声明一个Persons类用来包含所有的身份
@interface Persons {
Person[] value();
//@Repeatable 注解了 Person。而 @Repeatable 后面括号中的类相当于一个用来保存该注解内容的容器。
@Repeatable(Persons.class)
@interface Person{
String role default "";
//声明一个People类,给该类加上一些身份。
@Person(role="son")
@Person(role="father")
@Person(role="CEO")
public class People{
3.3 java预置的注解
(1)@Deprecated:用来标记过时的元素。
(2)@Override:提示子类要复写父类中被 @Override 修饰的方法;业可以做检查,编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错比如你如果没写@Override而你下面的方法名又写错了,这时你的编译器是可以通过的。
(3)@SuppressWarnings:阻止警告
(4)@SafeVarargs:参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。
(5)@FunctionalInterface:函数式接口注解,jdk1.8新特性
3.4 注解的提取
注解通过反射获取。首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解;然后通过 getAnnotation() 方法来获取 Annotation 对象(返回指定类型的注解);或者是 getAnnotations() 方法(返回注解到这个元素上的所有注解);
3.5 自定义注解
public class TestPerson {
public static void main(String[] args) {
Test1.show(Test1.class);
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@interface Person{
String name() default "aa"; //default "aa" 默认值
int age() default 18; //default 18 默认值
@Person(name="li",age=20)
class Test1{
public static void show(Class c) {
System.out.println(c.getName()); //Test1类的全路径
Person p =(Person)c.getAnnotation(Person.class);
System.out.println("name:"+p.name()+",age:"+p.age());
只有指定类
型
加入
泛
型
中才是安全的
这样读取的对象不需要强制转换类
型
泛
型
,JDK1.5新加入的,解决数据类
型
的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类
型
或者是某个方法的返回值及参数类
型
。这样在类声明或实例化时只要指定好需要的具体的类
型
即可。
Java
泛
型
可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁...
1.
泛
型
:
一、为什么要有
泛
型
(Generic)?1.解决元素存储的安全性问题任何类
型
都可以添加到集合中:类
型
不安全2.解决获取数据元素时,需要类
型
强转的问题读取出来的对象需要强转:繁琐可能有ClassCastException
1.
泛
型
的声明 interface List<T> 和 class TestGen<K,V> 其中,T,K,V不代表值,而是表示类
型
。这里使...