Java基础学习第二十五讲:自定义注解

自定义注解

一、什么是注解

Annontation是Java1.5开始引入的新特征,中文名称叫注解。
它提供了一种安全的类似注释的机制,用来将信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观、更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
注解和注释很像,注释是我们在开发中,提供给代码使用者或者是其他开发人员用来标注代码含义的功能;注解则是我们在开发中,通过注解向程序中的某个元素提供的相关信息,既是开发者告诉程序元素的内容,又可以作为程序元素为我们提供的相关信息的途径。

二、声明注解

Java基础学习第二十五讲:自定义注解_第1张图片
Java基础学习第二十五讲:自定义注解_第2张图片
注解的内容:

  • 基本数据类型
  • String
  • enum
  • Annotation
  • 以上类型的数组

注解的使用:注解中的属性内容可以存在任意个,根据业务的需求和需要设置的内容,设置不同的属性内容。

  • 属性内容可以通过default设置默认值,如果属性内容存在默认值,在使用注解时可以不为属性内容赋值,但是一旦赋值,则按照新的赋值内容进行处理。
  • 如果只有一个属性内容需要赋值,并且属性内容的名称是value,则value可以省略,直接定义值即可。
  • 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略

三、元注解

所有元注解定义在java.lang.annotation包下面,其中Annotation是注解的基本接口,所有的注解都继承这个接口。
java.lang.annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):

  1. @Documented:指定被标注的注解会包含在javadoc中。
  2. @Retention: 指定注解的生命周期(源码、class文件、运行时)
@Retention(RetentionPolicy.CLASS)//仅class文件可以使用
@Retention(RetentionPolicy.RUNTIME)//运行期可以使用
@Retention(RetentionPolicy.SOURCE)//仅编译期可以使用
  1. @Target:指定注解使用的目标范围(类、方法、字段等)
TYPE : 类、接口或enum声明
FIELD:(属性)声明
METHOD: 方法声明
PARAMETER: 参数声明
CONSTRUCTOR: 构造方法声明
LOCAL_VARIABLE:局部变量声明
ANNOTATION_TYPE:注释类型声明
PACKAGE: 包声明
  1. @Inherited:指定子类可以继承父类的注解,只能是类上的注解,方法和字段的注解不能继承。即如果父类上的注解是@Inherited修饰的就能被子类继承。

四、注解的应用

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})
public @interface MyAnnotation {

	public String name();
	public int val();
	
}
@MyAnnotation(name = "管理员信息", val = 1)
public class Admin {

	@MyAnnotation(name = "管理员姓名", val = 2)
	public String name;
	@MyAnnotation(name = "管理员年龄", val = 3)
	public int age;
	@MyAnnotation(name = "管理员构造方法", val = 4)
	public Admin() {
	}
	@MyAnnotation(name = "管理员自我介绍方法", val = 5)
	public void say() {
		System.out.println("我是管理员");
	}
}
public static void main(String[] args)throws Exception {
		Class c=Admin.class;
		Field f1=c.getDeclaredField("name");
		Field f2=c.getDeclaredField("age");
		
		Constructor con=c.getConstructor();
		
		Method m=c.getDeclaredMethod("say");
		
		MyAnnotation ma0=(MyAnnotation) c.getAnnotation(MyAnnotation.class);
		MyAnnotation ma1=f1.getAnnotation(MyAnnotation.class);
		MyAnnotation ma2=f2.getAnnotation(MyAnnotation.class);
		MyAnnotation ma3=(MyAnnotation) con.getAnnotation(MyAnnotation.class);
		MyAnnotation ma4=m.getAnnotation(MyAnnotation.class);
		
		System.out.println(ma0.name()+"---"+ma0.val());
		System.out.println(ma1.name()+"---"+ma1.val());
		System.out.println(ma2.name()+"---"+ma2.val());
		System.out.println(ma3.name()+"---"+ma3.val());
		System.out.println(ma4.name()+"---"+ma4.val());
	}

Java基础学习第二十五讲:自定义注解_第3张图片

五、通过自定义注解实现接口实现类注入

//声明自定义注解
@Retention(RUNTIME)
@Target(FIELD)
public @interface MyAnn {
	public String val();
}

//不在showview里面实例化
	public static void MyFac() {
		try {
		//获取要执行的类
		Class c=Class.forName("com.woniuxy.crm.view.ShowView");
		//通过属性名获取属性
		Field f=c.getDeclaredField("userService");
		//获取属性的注解
		MyAnn ma=f.getAnnotation(MyAnn.class);
		//根据注解的值进行加载
		Class c1=Class.forName(ma.val());
		//创建类的对象
		Object o=c.newInstance();
		//为注入的属性赋值
		f.set(o, c1.newInstance());
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
//属性通过注解赋值实现无需实例化注入对象
@MyAnn(val="com.woniuxy.crm.service.Impl.UserService")
	public static IUserService userService;

你可能感兴趣的:(Java基础学习,java,学习,开发语言)