java基础【注解】

一.注解理解

1、注解,或者叫做注释类型,英文单词是:Annotation
2、注解Annotation是一种引用数据类型。编译之后也是生成xxx.class文件。
3、怎么自定义注解呢?语法格式?

	 [修饰符列表] @interface 注解类型名{
	 }

4、注解怎么使用,用在什么地方?

  • 第一:注解使用时的语法格式是:
    @注解类型名
  • 第二:注解可以出现在类上、属性上、方法上、变量上等…
    注解还可以出现在注解类型上。

5、JDK内置了哪些注解呢?
java.lang包下的注释类型:

  • 掌握:
    Deprecated 用 @Deprecated 注释的程序元素,
    这个注解主要是向其他程序员传递一个信息,告知已过时,有更好的选择,
    不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。

  • 掌握:(表示性注解,给编译器参考的)
    1. Override 表示一个方法声明打算重写超类中的另一个方法声明。
    2. 这个注解只能注解方法,不能注解类,这个注解是给编译器参考的,和运行阶段没有关系。
    3. 凡是java中的方法带有这个注解的,编译器都会进行编译检查,如果不是重写父类方法,编译器报错。

  • 不用掌握:
    SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的
    所有程序元素)中取消显示指定的编译器警告。

6、元注解
什么是元注解?

  • 用来标注“注解类型”的“注解”,称为元注解。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{
}

(1)常见的元注解有哪些?
Target
Retention

(2)关于Target注解:
这是一个元注解,用来标注“注解类型”的“注解”
这个Target注解用来标注“被标注的注解”可以出现在哪些位置上。

@Target(ElementType.METHOD):表示“被标注的注解”只能出现在方法上。
			
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
	表示该注解可以出现在:
		构造方法上
		字段上
		局部变量上
		方法上
		....
		类上...

(3)关于Retention注解:
这是一个元注解,用来标注“注解类型”的“注解”
这个Retention注解用来标注“被标注的注解”最终保存在哪里。

@Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中。
@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中。
@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取。

7、Retention的源代码

//元注解	
public @interface Retention {
	//属性
	RetentionPolicy value();
}
RetentionPolicy的源代码:(枚举类型)
public enum RetentionPolicy {
	 SOURCE,
	 CLASS,
	 RUNTIME
}

//@Retention(value=RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{}

8、Target的源代码

//元注解	
public @interface Target{
	//数组
	ElementType[] value();
}
ElementType的源代码:(枚举)
public enum ElementType{
	 TYPE,
	 FIELD,
	 METHOD,
	 PARAMETER,
	 CONSTRUCTOR
}
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface MyAnnotation{}

二.自定义注解

1.自定义属性

//自定义的注解
public @interface MyAnnotation{
	
	String name();
	//颜色属性
	String color();
	int age() default 25; //属性指定默认值
}

//测试注解
public class MyAnnotationTest{
	//报错原因:如果一个注解当中有属性,那么必须给属性赋值(除非有默认值)
	
	//@MyAnnotation(属性名=属性值)
	@MyAnnotation(name = "zhangsan",color = "红色")
	public void doSome(){
	}
}

如果一个属性的名为value的时候,并且注解只有一个属性的时候,使用注解时可以省略赋值名 “hahaha”

public @interface MyAnnotation{
	String value();
}

@MyAnnotation("hahaha")
public void doSome(){
}

注解当中的属性可以是哪一种类型

  • 属性的类型可以是:
    byte short int Long float double boolean char String Class 枚举类型
    以及以上的每一种的数组形式。
public @interface OtherAnnotation {
	//年龄属性
	int age();
	//邮箱地址属性,支持多个
	String[] email();
	//季节数组,Season枚举类型
	Season[] seasonArray();
}

public class OtherAnnotationTest{
	//数组是大括号
	@OtherAnnotation(age = 25,email = {"zhangsan@123.com","zhangsan@sohu.com"},seasonArray = Season.WINTER)
	public void doSome(){}

	//如果数组中只有一个元素:大括号可以省略。
	@OtherAnnotation(age = 25,email = "zhangsan@123.com",seasonArray = {Season.SPRING,Season.SUMMER})
	public void doOther(){}
}

2.反射注解

注解类

public class ReflectAnnotationTest{
	public static void main(String[] args) throws Exception{
		//获取这个类
		Class c = Class.forName("com.tx.java.annotation.MyAnnotationTest");
		//判断类上上面是否有@MyAnnotation
		//System.out.println(c.isAnnotationPresent(MyAnnotation.class)); //true
		if(c.isAnnotationPresent(MyAnnotation.class)){
			//获取该注解对象
			MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);
			//System.out.println("类上面的注解对象"+myAnnotation);//@com.tx.java.annotation
			//获取注解对象的属性。
			String value = muyAnnotation.value();
			System.out.println(value); //北京新区
		}
		//判断String类上面是否存在这个注解
		Class stringClass = Class.forName("java.lang.String');
		System.out.println(stringClass.isAnnotationPresent(MyAnnotation.class)); //false
	}
}
@MyAnnotation("北京新区")
public class MyAnnotationTest{
	
}

注解方法

public class MyAnnotationTest{
	@MyAnnotation(username = "admin",password = "456456")
	public void doSome(){
	}
	public static void main(String[] args) throws Exception{
		//获取MyAnnotationTest的doSome()方法上面的注解信息。
		Class c = Class.forName("com.tx.java.annotation.MyAnnotationTest");
		//获取doSome()方法
		Method doSomeMethod = c.getDeclaredMethod("doSome");
		//判断该方法是否存在这个注解
		if(doSomeMethod.isAnnotationPresent(MyAnnotation.class)){
			MyAnnotation myAnnotation = doSomeMethod.getAnnotation(MyAnnotation.class);
			System.out.println(myAnnotation.username());
			System.out.println(myAnnotation.password());
		}
	}
}

三.注解在开发中有什么用呢?

需求:
假设有这样一个注解,叫做:@Id
这个注解只能出现在类上面,当这个类上有这个注解的时候,
要求这个类中必须有一个int类型的id属性。如果没有这个属性
就报异常。如果有这个属性则正常执行!

//获取类
Class userClass = Class.forName("com.tx.java.annotation.User");
//判断这个类中是否存在Id注解
if(userclass.isAnnotationPresent(Id.class)){
	//当一个类上面有@Id注解的时候,要求类中必须存在int类型的id属性
	//如果没有int类型的id属性则报异常。
	//获取类的属性
	Field[] fields = userClass.getDeclaredFields();
	boolean isOk = false;//给一个默认标记
	for(Field field : fields){
		if("id".equals(field.getName())&&"int".equals(field.getType().getSimpleName())){
			//表示这个类是合法的类,有@Id注解,则这个类中必须有int类型的id
			isOk = true; //表示合法
			break;
		}
	}
	//判断是否合法
	if(!isOk){
		throw new HasNotIdPropertyException("被@Id注解标注的类中必须要有一个int类型的id属性");
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值