有关注解的理解(Annotation)

注解的定义

package com.project;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
//定义了这个注解的含义就是这个注解可以定义在这个方法上
//TYPE 表示类、接口(包括注解接口)、枚举或记录(record)的声明。
//FIELD 示字段声明,这包括了枚举常量。
//METHOD  表示方法声明。
//PARAMETER 表示形式参数声明,即方法或构造函数的参数
//CONSTRUCTOR   表示构造函数声明。
//LOCAL_VARIABLE  示局部变量声明,即在方法或构造函数内部声明的变量。
//TYPE_PARAMETER 表示类型参数声明,用于泛型中声明类型变量。这个枚举值从Java 8开始引入。
//后面还有一部分但是感觉不是很重要也就没有去总结
@Retention(RetentionPolicy.RUNTIME)
//SOURCE  使用 SOURCE 保留策略的注解仅在源代码中保留,它们不会被编译器记录在类文件中。这意味着这些注解在编译时会被忽略,不会对运行时行为产生任何影响。
//CLASS   使用 CLASS 保留策略的注解会被编译器记录在类文件中,但不会被保留在Java虚拟机(JVM)的运行时。这意味着这些注解在类加载时可用,但无法通过反射在运行时访问。
//RUNTIME  使用 RUNTIME 保留策略的注解不仅会被编译器记录在类文件中,还会被JVM在运行时保留。这意味着这些注解可以通过反射在运行时被访问和处理。
public @interface MyAnnotation {
	/**
	 * 一下这个是注解的name属性
	 *
	 * @return name 属性
	 */
	String name();
	
	/**
	 * 颜色属性
	 *
	 * @return
	 */
	String color();
	
	/**
	 * 年龄的属性
	 * 默认的值为23
	 * 这个可以不用去写使用了这个default就可以不用去写这个属性但是不代表这个属性就没有了
	 * 他只是存在这个默认的值
	 *
	 * @return
	 */
	int age() default 23;
	
	String value();
	
	int value1();
	
	int[] value2();
	
	String[] value3();
	
	Class<?> parameterType();
	
	Class<?>[] parameterTypes();
	
	Season season();
	/**
	 * byte short int float double String class enum boolean
	 */
}

二.通过一个例子你就可以理解这个注解(Annotation)是如何作用在这个方法字段以及…

package com.project;

import jdk.jfr.Experimental;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 创建一个注解
 * 注解被成为注释类型
 */
@Target({ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
/**
 * 这个就表示这个只能出现在这个java源文件当中
 */
public @interface annotationCreat {
 String value();
 String name();
}


//测试类
package com.project;

import org.junit.Test;

/**
 * 注解在哪一个地方都可以出现在不指定的情况下可以出现在任何的地方
 */
@annotationCreat(value = "1", name = "1")
public class AnnotationTest {
	private int a;
	@annotationCreat(value = "", name = "")
	private String name;
	
	@annotationCreat(value = "", name = "")
	@Test
	public void test1() {
		@annotationCreat(value = "", name = "")
		int i;
	}
	
	@annotationCreat(value = "", name = " ")
	public AnnotationTest(int a, String name) {
		this.a = a;
		this.name = name;
	}
	
	@annotationCreat(value = "", name = "")
	public AnnotationTest() {
	}
	
	@annotationCreat(value = "", name = "")
	private void test2() {
		
	}
	
	private void test3(@annotationCreat(value = "", name = "") String... args) {
		
	}
	
	private void test4(@annotationCreat(value = "", name = "") String name, @annotationCreat(value = "", name = "") String password) {
		
	}
}

三.对这个overwried注解的理解

package com.project;

import org.junit.Test;

/**
 * jdk当中自己有多少的注解
 * java lang包下的注解;类型
 * @Target(ElementType.METHOD)  只能出现在这个方法上面
 * @Retention(RetentionPolicy.SOURCE)  这个是给这个编译器看的编译阶段会进行检查  不添加这个注解也可以但是这样组做也是为了避免
 * 出现错误
 * public @interface Override {
 * }
 */
public class AnnotationTest2 {
	@Override
	/**
	 * 这个注解可以出现在这个方法上面
	 * 在编译时候进行运行
	 * 编译器进行检查这个注解和这个运行无关
	 */
	public String toString() {
		return super.toString();
	}
}
//下面的是源码 明显的看到这个只能作用子啊这个方法上面而且也只是保存在这个编译阶段这个不会被这个加载在这个jvm虚拟机的内存中*(简答的说就是他不会在这个产生的class文件当中存在)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

四加深一下对这个注解使用的理解(代码里面先对这个方法进行获取获取之后对这个方法上进行判断是否含有这个注解获取这个注解上的内容对这个注解上的内容进行调用)

//注解类
package com.project;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//可以被这个反射机制读取
public @interface loginAnnotation {
	String username();
	String password();
}
//测试类
package com.project;

import org.junit.Test;

import java.lang.annotation.Target;
import java.lang.reflect.Method;

/**
 * 测试这个注解上的内容是否可以dengru
 */
public class AnnotationUser {
	@Test
	public void testlogin() throws  Exception
	{
		Class<?> aClass = Class.forName("com.project.User");
		Method[] methods = aClass.getDeclaredMethods();
		Object obj = aClass.newInstance();
		for (Method method : methods) {
			/**
			 * 因为只有一个方法在这个地方也就不许要去进行判断了;
			 */
			if (method.isAnnotationPresent(loginAnnotation.class)) {
//				System.out.println("true");
				loginAnnotation annotation = method.getAnnotation(loginAnnotation.class);
				String password = annotation.password();
				String username = annotation.username();
				Object invoke = method.invoke(obj, username, password);
//				System.out.println(invoke);
			}else {
//				System.out.println("fasle");
			}
		}
			}
}

五进一步加深对这个注解的理解

package com.project;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.CONSTRUCTOR, ElementType.TYPE,ElementType.METHOD})
/**
 * 在这个地方就是设置它可以被这个反射机制读取到这个数据
 */
@Retention(value=RetentionPolicy.RUNTIME)
//在这个地方要设置为这个runtime才行这样才可以获取到获取这个值这个就是反射机制的神奇的地方之一
public @interface otherAnnotation {
	/**
	 * 年龄属性
	 * @return
	 */
	int age();
	
	/**
	 * 邮箱属性
	 * @return
	 */
	String[] email();
	
	/**
	 * 季节数
	 * @return
	 */
	Season[] seasonArrays();
	
}
//设置一个类在这个类上设置注解并且对这个注解进行赋值
package com.project;

import org.junit.Test;
@otherAnnotation(age = 12,email = "ds",seasonArrays = Season.SPRING)
public class OtherAnnotationTest {
	@otherAnnotation(age = 12,email = "sd",seasonArrays = Season.SPRING1)
	public OtherAnnotationTest() {
	}
	/**
	 *如果数组当中只有一个元素大括号可以省去但是初学者还是要记住
	 */
	@Test
	@otherAnnotation(age = 23,email = {"23@qq.com","张三.@qq.com"},seasonArrays = {Season.SPRING,Season.SPRING1})
	public void test1()
	{
	
	}
}

//获取这个注解上的内容
package com.project;

import java.util.Arrays;

public class ReflectAnnotation {
	public static void main(String[] args)  throws Exception{
//		获取这个类
		Class<?> aClass = Class.forName("com.project.OtherAnnotationTest");
//		查看是否有这个注解
		boolean is = aClass.isAnnotationPresent(otherAnnotation.class);
//		System.out.println(is);
//		显示这个注解已经存在了已经含有这个注解
		otherAnnotation annotation = aClass.getAnnotation(otherAnnotation.class);
//		System.out.println(annotation);
//		@com.project.otherAnnotation(age=12, email={"ds"}, seasonArrays={SPRING})
//		这个就是类上面的注解对象 如果有这个注解的话就可以获取这个值
		int age = annotation.age();
//		System.out.println(age);
		Season[] seasons = annotation.seasonArrays();
		for (Season season : seasons) {
			System.out.println(season);
		}
//		这就是获取这个注解上的内容
		String[] email = annotation.email();
		Arrays.stream(email).forEach(s -> {
			System.out.println(s);
		});
//		有这个注解就去获取这个注解就欧克了
 
	}
}

六.最后还有一个注解就是使用这个注解你就可以知道这个类或者这个方法是废弃的在实际的应用当中还是十分的管用的

package com.project;
//表示这个类已经过时了

/**
 * 这个就是提示用户的作用
 */
@Deprecated(since = "6")
public class AnnotationDeprecated {
	public static void main(String[] args) {
	    test1();
	}
	@Deprecated
	public  static void test1()
	{
	
	
	}
	public void test2()
	{
	
	}
}

/**
 * 这个就是告诉别人这个方法和这个类已经过时了有跟好的解决方式i出现
 */
class test{
	public static void main(String[] args) {
		AnnotationDeprecated.test1();
	}
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值