注解

1. 注解的使用
  * 定义注解类:框架的工作
  * 使用注解:我们的工作
  * 读取注解(反射):框架的工作,tomcat利用反射,读取servlet 中的注解的

3 Java中的注解

Java中的觉注解:

  1. @Overrid:作用在方法上的注解。检查方法是不是父类继承的方法,当方法不是重写父类的方法时会报错;
  2. @Deprecated:作用在方法上。标记该方法为作废方法(已过时);
  3. @SuppressWarnings:作用在方法上,压制警告

 @interface A{}//天下所有的注解都是Annotation的子类

4 使用注解目标

  注解可以作用在:类(接口或枚举)、属性、方法、构造器、包(可以放,但是一般不用特殊方法可以放)、参数、局部变量

package cn.itcast.annocation;

 

@MyAnn

public class MyClass {

    @MyAnn

    private int a;

    @MyAnn

    public MyClass() {}

    @MyAnn

    public void fun1() {}

    @MyAnn

    public void fun2(@MyAnn String s) {

       @MyAnn

       int n = 10;

    }

}

5 注解的属性

 

4. 使用注解
  注解的作用目标:
    * 类
    * 方法
    * 构造器
    * 参数
    * 局部变量
    * 包

5. 注解的属性
  * 定义属性:
    > 格式:
    @interface MyAnno1 {
    int age();
    String name();
    }
  * 使用注解时给属性赋值
    > @MyAnno1(age=100, name="zhangSan")
  * 注解属性的默认值:在定义注解时,可以给注解指定默认值!
    > int age() default 100;
    > 在使用注解时,可以不给带有默认值的属性赋值!
  * 名为value的属性的特权
    > 当使用注解时,如果只给名为value的属性赋值时,可以省略“value=”,例如: @MyAnno1(value="hello"),可以书写成 @MyAnno1("hello")
  * 注解属性的类型
    > 8种基本类型
    > String
    > Enum
    > Class
    > 注解类型
    > 以上类型的一维数组类型(二维数组都不行)
  

@MyAnno1(
	a=100,
	b="hello",
	c=MyEnum1.A,
	d=String.class,
	e=@MyAnno2(aa=200, bb="world"),
	f=100//  当给数组类型的属性赋值时,若数组元素的个数为1时,可以省略大括号{100,200} {100}
)
public class Demo3 {

}

@interface MyAnno1 {
	int a();
	String b();
	MyEnum1 c();
	Class d();
	MyAnno2 e();
	int[] f();
}

@interface MyAnno2 {
	int aa();
	String bb();
}

enum MyEnum1 {
	A, B, C
}


}

定义注解时也可以给出属性

public @interface MyAnn {

    String value();

    int value1();

}

 

其中value就是属性!你可能会说,它是一个方法!没错,它是一个方法,但我们非要称之为属性,因为把它当做属性更加好理解。

当为注解指定属性后,那么在使用注解时就必须要给属性赋值了:

@MyAnn(value1=100,value="hello")

public class MyClass {

}

 

注解的属性还可以有默认值,在使用注解时就可以不给带有默认值的属性赋值了。但没有给出默认值的属性还是要赋值的。

 

public @interface MyAnn {

    String value() default "hello world";

    int value1();

}

@MyAnn(value1=100)

使用注解时,没有给出value属性,因为它有默认值,可以不赋值。但value1没有默认值就必须赋值。当然也可以给带有默认值的属性赋值。

public class MyClass {

}

 

在使用注解时,如果只给名为value的属性赋值,那么可以不给出属性的名称直接给出值。

public @interface MyAnn {

    String value() default "hello world";

    int value1() default 100;

}

@MyAnn()

因为所有属性都有默认值,所以没问题

public class MyClass {

}

@MyAnn(value="hello")

public class MyClass {

}

@MyAnn(value1=200)

public class MyClass {

}

@MyAnn(value="hello",value1=200)

public class MyClass {

}

@MyAnn("hello annocation")

因为value属性是String类型的,所以出错

public class MyClass {

}

@MyAnn(300)

因为value属性是String类型的,所以出错

public class MyClass {

}

@MyAnn("hello",value1=200)

出错!因为不是给一个属性赋值,那么这时就不能再省略属性的名字。

public class MyClass {

}

 

 

6. 注解的作用目标限定以及保存策略限定

  1. 注解的属性后面要有一对圆括号,而且圆括号内不能给出东西。就像是无参的方法一样;
  2. 注解的属性类型只能是:基本类型、String、Enum、Class、注解类型、以上类型的一维数组类型;
  3. 注解的属性可以有默认值,例如:int a() default 100;
  4. 数组的属性默认值:int[] arr() default {1,2,3},这里不能使用new int[]{1,2,3}
  5. 使用注解时,在给数组属性赋值时的格式:@MyAnn(arr={1,2,3});

6 注解的作用目标

在定义注解时可以限制注解的作用目录!例如让注解只能作用在类和方法上。

这需要使用元注解:@Target。该注解有一个属性value,类型为ElementType[],它是枚举类型。

 

public @interface Target {

    ElementType[] value();

}

public enum ElementType {

  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE

}

 

在定义注解时,可以使用@Target注解来限制注解的作用目标:

@Target({ElementType.TYPE, ElementType.METHOD})

public @interface MyAnn {

}

 

这样MyAnn就只能作用在类和方法上的!其中ElementType.TYPE表示类和接口。

@MyAnn()

public class MyClass {

出错!因为MyAnn被限制只能作用在类和方法上,不能作用在属性上。

    @MyAnn()

    private int a;

   

    @MyAnn()

    public void fun() {}

}

 

7 注解的保留策略

注解的保留策略是指,注解是只保留在源代码上,还是保留到class文件上,再或者是类在运行时,可以被类加载器加载到内存中。

如果希望注解被反射,那么注解就要保留到运行时,而不是源代码或类文件上。

指定注解的保留策略需要使用元注解@Retention,它有一个value属性,类型为RetentionPolicy类型,RetentionPolicy是枚举类型:

public @interface Retention {

    RetentionPolicy value();

}

public enum RetentionPolicy {

    SOURCE, CLASS, RUNTIME

}

 

下面代码是指定注解保留到运行时

@Retention(RetentionPolicy.RUNTIME)

注解保留到运行时

@Target({ElementType.TYPE, ElementType.METHOD})

public @interface MyAnn {

    String value() default "hello";

    int value1() default 100;

}

 

8 通过反射读取注解

读取注解需要使用反射来完成

@Retention(RetentionPolicy.RUNTIME)

保留到运行时,如果不设置为保留到运行时,那么就无法反射出来

@Target({ElementType.TYPE, ElementType.METHOD})

public @interface MyAnn {

    String value() default "hello";

    int value1() default 100;

}

@MyAnn(value="hello world", value1=200)

public class MyClass {

    private int a;

   

    @MyAnn("myMethod")

    public void fun() {}

}

public class Demo1 {

    public static void main(String[] args) throws Exception {

        Class clazz = MyClass.class;

       MyAnn myAnn = (MyAnn) clazz.getAnnotation(MyAnn.class);

       System.out.println(myAnn.value());

       System.out.println(myAnn.value1());

      

       Method method = clazz.getMethod("fun");

       MyAnn myAnn1 = method.getAnnotation(MyAnn.class);

       System.out.println(myAnn1.value());

       System.out.println(myAnn1.value1());

    }

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值