java的注解

java的注解

1.注解的含义

注解和接口与类一样,都属于数据类型。

2.注解的作用

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 编写文档
 * @author wf
 *
 */
//代码分析(做配置)
@WebServlet("/t1")
public class t1 extends HttpServlet {
	
	//编译检查:
	@Override
	public String toString() {
		return "t1 []";
	}
/*
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}*/
}

1.编译检查:通过代码中标识的注解,让编译器实现基本的编译检查。如:@Override

2.代码分析(做配置):通过注解,对代码分析,取代xml的作用

3.编写文档:通过注解生成帮助文档

3.注解的特点

1.注解可以在变量,方法与类上加载

2.注解可以有属性,也可以不包含属性 @Override @Text(timeout=1000)

3.注解的作用范围(a.源码 b.编译期间 c.运行期间)

​ a.源码期间有效:String类上的@Author @Since @See

​ 作用:使命令javadoc将当前的源码生成帮助文档,可识别String上的相关注解

​ b.编译期间有效:@Override @Deprecated @Suppresswaming

​ 作用:告诉编译器部分信息

​ c.运行期间有效:@Text

​ 作用:当我们再当前代码上以Junit方式运行时,Junit会运行方法上包含@Test注解的方法

//注释含义:如果执行时长超过1s就报错
	@Test(timeout=1000)
	public static void tset03() {
		
	}

4.jdk提供的3种注解

@Override @Deprecated @Suppresswarning

public class a1 {
		
	//注解含义:声明当前方法是重写的父类方法
	@Override
	public String toString() {
		return super.toString();
	}
	
	public static void name() {
		//以下注解的含义是:抑制编译器发生警告信息
		@SuppressWarnings(value = { "unused" })
		int a;
		@SuppressWarnings("unused")
		int i;
		//以下注解的含义是:抑制编译器发生警告信息(如果有变量未使用,未遵循泛型格式错误不报警告)
		@SuppressWarnings(value = {"unused","rawtypes"})
		List list = new ArrayList();
	}
    
	//注解含义:说明当前的方法已过时,不建议使用
	@Deprecated
	public static void name1() {
		System.out.println("fqegf");
	}
}

5.自定义注解

格式

public @interface 注解名称{

​ public 属性类型 属性名称1();

​ public 属性类型 属性名称2() default 默认值;

}

import java.util.Date;

public @interface myAnno {
	//定义一个变量
	public int a();
	//定义一个变量,设置其默认值为-1
	public long timeout() default -1;
	//支持类型的一维数组
	public String[] strs();
	//报错:原因:属性不支持自定义类类型
	//public Date date();
	
}

自定义注解中成员变量支持的类型

基本数据类型(4类8种),String, Class ,Annotation(注解类型),枚举类型,及以上类型的一维数组类型

框架:一大堆工具类组合,目的:加速项目开发

后期的学习中,框架部分hibernate,spring,struts2很多信息需要配置,提供了2种形式配置 (xml,注解)

什么时候用注解来做配置?

如果配置信息不会发生修改,如:servlet的路径,建议使用注解做配置

如果配置信息需要发生频繁的修改,如:用户的姓名和密码,采用传统方式配置(.txt .xml .properties)

<students>

  <stu>

   <stuNum>s002</stuNun>

   <stuPhone>

      <stuHomePhone>124324</stuHomePhone>

      <stuCmpPhone>12342143</stuCmpPhone>

   </stuPhone>

  </stu>

</students>

测试自定义注解

1_自定义注解@MyTest

通过元注解@Rentention @Target声明当前注解作用域以及目标对象,如果没有声明,在运行期间是无法获取到注解的信息

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

//自定义注解,相当于JUnit@Test

//定义注解的时候,需要通过元注解Retention说明当前自定义注解的作用域(Class,Source,Runtime)
@Retention(RetentionPolicy.RUNTIME)
//定义注解的时候,需要通过元注解Target说明当前的自定义注解的目标对象
@Target(ElementType.METHOD)
public @interface MyAnno {
	//在MyTest注解中定义成员属性,默认值为-1
	public int a() default 1;

}

2_定义UserDao

创建4个方法addUser delUser uptUser getUser ,在前三个方法上加载注解

public class Userdao {
	static{
		System.out.println("加载静态代码段的消息");
	}
	
	@MyAnno
	public void addUser(){
		System.out.println("增加用户");
	}
	@MyAnno
	public void delUser(){
		System.out.println("删除用户");
	}
	@MyAnno
	public void uptUser(){
		System.out.println("更新用户");
	}
	public void getUser(){
		System.out.println("获取用户");
	}
}

3_定义类MyJunit ,模拟JUnit

将UserDao.class文件加载到内存,

获取到字节码文件上所有的方法

遍历方法,判断每个方法上是否加载了@MyTest注解

如果当前方法上设置@MyTest,执行当前的方法

import java.lang.reflect.Method;


public class Myjunit {
  public static void main(String[] args) throws Exception {
  	//加载UserDao.class字节码文件中的方法,判断哪些方法上有自定义的注解@MyTest,如果当前的方法有@MyTest,执行,否则不执行
  	//1_将UserDao.class字节码文件加载到内存中 ,class对象(代表字节码文件在内存中的对象)
  	Class c1 = Class.forName("testAnno.Userdao");
  	Class c2 = Userdao.class;
  	Userdao u = new Userdao();
  	Class c3 = u.getClass();
  	//2_获取字节码对象上所有的方法,返回Method数组对象,数组中的每一个元素都代表Method对象(相当于字节码上的每一个方法)
  	Method[] mds = c1.getMethods();
  	//3_遍历字节码对象上所有的方法
  	for (Method md : mds) {
  		//测试方法的名称
  		System.out.println(md.getName());
  		//判断当前方法上是否有@MyTest注解信息
  		//md.invoke(new UserDao());
  		System.out.println(md.isAnnotationPresent(MyAnno.class));
  		if(md.isAnnotationPresent(MyAnno.class)){
  			//如果当前的方法上有@MyTest注解,执行,否则忽略
  			md.invoke(new Userdao());
  		}
  	}
  }
}

注:通过反射来读取字节码上的注解信息。md.isAnnotationPresent(MyTest.class)"

原文地址:https://www.cnblogs.com/wf614/p/11673836.html