这是我参与更文挑战的第28天,活动详情查看: 更文挑战java
spring开源框架,里面全是经过注解实现的spring
spring开源框架,里面全是经过注解实现的,咱们使用在使用的时候也尝到很多好处,因此就抽空看看Java给咱们提供的注解机制的使用。编程
Overridemarkdown
SuppressWarningsapp
- deprecation,使用了过期的类或方法时的警告
- unchecked,执行了未检查的转换时的警告
- fallthrough,当 switch 程序块直接通往下一种状况而没有 break 时的警告
- path,在类路径、源文件路径等中有不存在的路径时的警告
- serial,当在可序列化的类上缺乏serialVersionUID 定义时的警告
- finally ,任何 finally 子句不能正常完成时的警告
- all,关于以上全部状况的警告
复制代码
Deprecated框架
它的做用是对不该该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能,准确的说,它还不如javadoc @deprecated,由于它不支持参数,使用@Deprecated的示例代码示例以下:
ide
ElementTypesvn
RetentionPolicy函数
Documented工具
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*
* @author Joshua Bloch
* @since 1.5
*/
复制代码
Target
/**
* Indicates the kinds of program element to which an annotation type
* is applicable. If a Target meta-annotation is not present on an
* annotation type declaration, the declared type may be used on any
* program element. If such a meta-annotation is present, the compiler
* will enforce the specified usage restriction.
*
* For example, this meta-annotation indicates that the declared type is
* itself a meta-annotation type. It can only be used on annotation type
* declarations:
* <pre>
* @Target(ElementType.ANNOTATION_TYPE)
* public @interface MetaAnnotationType {
* ...
* }
* </pre>
* This meta-annotation indicates that the declared type is intended solely
* for use as a member type in complex annotation type declarations. It
* cannot be used to annotate anything directly:
* <pre>
* @Target({})
* public @interface MemberType {
* ...
* }
* </pre>
* It is a compile-time error for a single ElementType constant to
* appear more than once in a Target annotation. For example, the
* following meta-annotation is illegal:
* <pre>
* @Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
* public @interface Bogus {
* ...
* }
* </pre>
*/
复制代码
一样上面仍然是Java JDK官网的说明,首先是说若是target指定的类型元素不存在的话,那么经过target指定的注解将能够用在任何地方,若是target指定元素,则该注解必须只能用在指定的元素上,target指定的元素是经过ElementType这个枚举类指定的,里面的枚举就是target能够指定的值。官网上的列子是Target(ElementType.ANNOTATION_TYPE)代表这个注解只能用在注解本省上面。还有一种属性不在ElementType枚举中,就是target({})
,就是经过{}的注解是用来在负责注解上的成员变量,他不能用在其余的地方。
ElementType.CONSTRUCTOR:用于描述构造器
ElementType.FIELD:成员变量、对象、属性(包括enum实例)
ElementType.LOCAL_VARIABLE:用于描述局部变量
ElementType.METHOD:用于描述方法
ElementType.PACKAGE:用于描述包
ElementType.PARAMETER:用于描述参数
ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
Retention
/**
* Indicates how long annotations with the annotated type are to
* be retained. If no Retention annotation is present on
* an annotation type declaration, the retention policy defaults to
* {@code RetentionPolicy.CLASS}.
*
* <p>A Retention meta-annotation has effect only if the
* meta-annotated type is used directly for annotation. It has no
* effect if the meta-annotated type is used as a member type in
* another annotation type.
*
* @author Joshua Bloch
* @since 1.5
*/
复制代码
这个类的属性是经过RetentionPolicy这个枚举类列举属性的,这个主要的做用是指定咱们的注解存在的时间或者说是存在的时刻。这个属性只有直接用在原注释类型的注解上才有效。若是用在其余注解的成员变量上就没有效果了。
RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束以后就再也不有任何意义,因此它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
- RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,所以可使用反射机制读取该注解的信息。咱们自定义的注解一般使用这种方式。
复制代码
Inherited
/**
* Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type. This process will be repeated until an annotation for this
* type is found, or the top of the class hierarchy (Object)
* is reached. If no superclass has an annotation for this type, then
* the query will indicate that the class in question has no such annotation.
*
* <p>Note that this meta-annotation type has no effect if the annotated
* type is used to annotate anything other than a class. Note also
* that this meta-annotation only causes annotations to be inherited
* from superclasses; annotations on implemented interfaces have no
* effect.
*
* @author Joshua Bloch
* @since 1.5
*/
复制代码
/**
* 该注解用于doc文档
* 该注解用于类的构造函数的注解
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConstructorAnno
{
String decs() default "我是描述构造函数的注解";
}
复制代码
/**
* 该注解用于生成doc文档
* 该注解用于在类的字段属性上的注解
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnno
{
String desc() default "我是描述字段的注解";
}
复制代码
/**
* 该注解用于生成doc文档
* 该注解用于在局部变量上的注解
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.LOCAL_VARIABLE)
@Retention(RetentionPolicy.RUNTIME)
public @interface LocalAnno
{
String desc() default "我是描述一个局部变量的注解";
}
复制代码
/**
* 这个注解用于生成doc文档
* 这个注解用于类的方法上的注解
* 这个注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnno
{
//默认提交时间 2017-2-28
String time() default "2017-2-28";
//默认 男 true 男 false 女
boolean sex() default true;
}
复制代码
/**
* 该注解用于生成doc文档
* 该注解用于在包的注解
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PackageAnno
{
String desc() default "我是描述包的注解";
}
复制代码
/**
* 该注解用于doc文档的生成
* 该注解用于类的参数中
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface StuInfo
{
String value() default "";
}
复制代码
/**
* 该注解用于生活曾doc文档
* 该注解用于在类的注解
* 该注解尽在运行期间有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeAnno
{
String desc() default "我是描述类型的注解";
}
复制代码
/**
* 测试全部类型的注解的做用
* @author xinhua
*
*/
public @TypeAnno(desc="我是普通类")class User
{
@FieldAnno
private String UID;
@FieldAnno(desc="我是UserName的")
private String userName;
@ConstructorAnno
public User(){
}
@MethodAnno(time="2015-12-8" , sex=false)
public void doHomeWork(@StuInfo(value="211311084") String UID, @StuInfo(value="张新华")String UserName){
@LocalAnno(desc="flag的局部变量")boolean flag;
}
}
复制代码
public interface UserImp
{
public void DoHouseWork(@StuInfo(value="我是小学生")String stuType,@StuInfo(value="我在大扫除")String things);
}
复制代码
/**
* 开始经过反射获取注解内容
* @author xinhua
*
*/
public class Junit
{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException
{
Class<?> userClass = Class.forName("tom.change.annotation.User");
//实例化
Object userObject = userClass.newInstance();
//1--获取最外层的就是类的注解 TypeAnno
System.out.println(".......................类注解.......................");
TypeAnno typeAnno= userClass.getAnnotation(TypeAnno.class);
System.out.println(typeAnno.desc());
//2--获取字段注解 首先获取经过反射获取类中的属性字段
System.out.println(".......................字段注解.......................");
Field[] fields = userClass.getDeclaredFields();
for (Field field : fields)
{
FieldAnno fieldAnno = field.getAnnotation(FieldAnno.class);
System.out.println(fieldAnno.desc());
}
//3-- 方法的注解
System.out.println(".......................方法注解.......................");
Method method = userClass.getMethod("doHomeWork", String.class,String.class);
MethodAnno methodAnno = method.getAnnotation(MethodAnno.class);
System.out.println(methodAnno.time()+"@@@"+methodAnno.sex());
//4-- 参数的注解 动态代理方式实现参数
System.out.println(".......................参数注解.......................");
UserImp userImp=getMethodParameter(UserImp.class);
userImp.DoHouseWork("张新华", "--》扫地");
//5--局部变量注解
System.out.println(".......................局部变量注解.......................");
//赞未得到到
}
public static<T> T getMethodParameter(Class<T> target){
return (T)Proxy.newProxyInstance(target.getClassLoader(), new Class<?>[]{target}, new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i=0;i<parameterAnnotations.length;i++)
{
Annotation[] annotations=parameterAnnotations[i];
StuInfo stuInfo =(StuInfo) annotations[0];
System.out.println(stuInfo.value()+"@@@"+args[i]);
}
return null;
}
});
}
}
复制代码