1>注解介绍
注解,或者叫做注释类型,英文单词是:Annotation
注解Annotation是一种引用数据类型。编译之后也是生成xxx.class文件。
2>自定义注解的语法格式
[ 修饰符列表] @interface 注解类型名{
}
3>如何使用注解
第一:注解使用时的语法格式是: @注解类型名 第二:注解可以出现在类上、属性上、方法上、变量上等… 注解还可以出现在注解类型上。
package com. bjpowernode. java. annotation;
public @interface MyAnnotation {
}
package com. bjpowernode. java. annotation;
@MyAnnotation
public class AnnotationTest01 {
@MyAnnotation
private int no;
@MyAnnotation
public AnnotationTest01 ( ) { }
@MyAnnotation
public static void m1 ( ) {
@MyAnnotation
int i = 100 ;
}
@MyAnnotation
public void m2 ( @MyAnnotation
String name,
@MyAnnotation
int k) {
}
}
@MyAnnotation
interface MyInterface {
}
@MyAnnotation
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
4>注解的属性
4.1、属性基础
package com. bjpowernode. java. annotation2;
public @interface MyAnnotation {
String name ( ) ;
String color ( ) ;
int age ( ) default 25 ;
}
package com. bjpowernode. java. annotation2;
public class MyAnnotationTest {
@MyAnnotation ( name = "zhangsan" , color = "红色" )
public void doSome ( ) {
}
}
4.2、关于value的特殊情况
package com. bjpowernode. java. annotation3;
public @interface MyAnnotation {
String value ( ) ;
}
package com. bjpowernode. java. annotation3;
public class MyAnnotationTest {
@MyAnnotation ( value = "hehe" )
public void doSome ( ) {
}
@MyAnnotation ( "haha" )
public void doOther ( ) {
}
}
4.3、属性为数组情况
package com. bjpowernode. java. annotation4;
public @interface MyAnnotation {
int value1 ( ) ;
String value2 ( ) ;
int [ ] value3 ( ) ;
String[ ] value4 ( ) ;
Season value5 ( ) ;
Season[ ] value6 ( ) ;
Class parameterType ( ) ;
Class[ ] parameterTypes ( ) ;
}
package com. bjpowernode. java. annotation4;
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 ( ) {
}
}
5>JDK内置的常用注解
java.lang包下的注释类型:
掌握:
Deprecated 用 @Deprecated 注释的程序元素,
不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。
掌握:
Override 表示一个方法声明打算重写超类中的另一个方法声明。
不用掌握:
SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的
所有程序元素)中取消显示指定的编译器警告。
5.1、@Override
package com. bjpowernode. java. annotation;
public class AnnotationTest02 {
private int no;
@Override
public String toString ( ) {
return "toString" ;
}
}
5.2、@Deprecated
如果main()方法中调用了某个已过时的方法,方法名中间会出现一条横线(IDEA中)
package com. bjpowernode. java. annotation;
@Deprecated
public class AnnotationTest03 {
@Deprecated
private String s;
public static void main ( String[ ] args) {
AnnotationTest03 at = new AnnotationTest03 ( ) ;
at. doSome ( ) ;
}
@Deprecated
public void doSome ( ) {
System. out. println ( "do something!" ) ;
}
@Deprecated
public static void doOther ( ) {
System. out. println ( "do other..." ) ;
}
}
class T {
public static void main ( String[ ] args) {
AnnotationTest03 at = new AnnotationTest03 ( ) ;
at. doSome ( ) ;
AnnotationTest03. doOther ( ) ;
try {
Class c = Class. forName ( "java.util.Date" ) ;
Object obj = c. newInstance ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
6>元注解
6.1、什么是元注解?
用来标注“注解类型”的“注解”,称为元注解。
6.2、常用的元注解
6.2.1、 @Target
这是一个元注解,用来标注“注解类型”的“注解”
这个Target注解用来标注“被标注的注解”可以出现在哪些位置上。
@Target(ElementType.METHOD):表示“被标注的注解”只能出现在方法上。
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
表示该注解可以出现在:
构造方法上
字段上
局部变量上
方法上
....
类上...
6.2.2、@Retention
这是一个元注解,用来标注“注解类型”的“注解”
这个Retention注解用来标注“被标注的注解”最终保存在哪里。
@Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中。
@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中。
@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,
并且可以被反射机制所读取。
6.2.3、例子
package com. bjpowernode. java. annotation5;
import java. lang. annotation. ElementType;
import java. lang. annotation. Retention;
import java. lang. annotation. RetentionPolicy;
import java. lang. annotation. Target;
@Target ( { ElementType. TYPE, ElementType. METHOD} )
@Retention ( RetentionPolicy. RUNTIME)
public @interface MyAnnotation {
String value ( ) default "北京大兴区" ;
}
7>利用反射机制判断注解
7.1、判断类上注解是否存在并返回注解的属性
package com. bjpowernode. java. annotation5;
import java. lang. annotation. ElementType;
import java. lang. annotation. Retention;
import java. lang. annotation. RetentionPolicy;
import java. lang. annotation. Target;
@Target ( { ElementType. TYPE, ElementType. METHOD} )
@Retention ( RetentionPolicy. RUNTIME)
public @interface MyAnnotation {
String value ( ) default "北京大兴区" ;
}
package com. bjpowernode. java. annotation5;
@MyAnnotation ( "上海浦东区" )
public class MyAnnotationTest {
int i;
public MyAnnotationTest ( ) {
}
@MyAnnotation
public void doSome ( ) {
int i;
}
}
package com. bjpowernode. java. annotation5;
public class ReflectAnnotationTest {
public static void main ( String[ ] args) throws Exception{
Class c = Class. forName ( "com.bjpowernode.java.annotation5.MyAnnotationTest" ) ;
if ( c. isAnnotationPresent ( MyAnnotation. class ) ) {
MyAnnotation myAnnotation = ( MyAnnotation) c. getAnnotation ( MyAnnotation. class ) ;
String value = myAnnotation. value ( ) ;
System. out. println ( value) ;
}
Class stringClass = Class. forName ( "java.lang.String" ) ;
System. out. println ( stringClass. isAnnotationPresent ( MyAnnotation. class ) ) ;
}
}
7.2、判断方法注解是否存在并返回注解属性
package com. bjpowernode. java. annotation6;
import java. lang. annotation. ElementType;
import java. lang. annotation. Retention;
import java. lang. annotation. RetentionPolicy;
import java. lang. annotation. Target;
@Retention ( RetentionPolicy. RUNTIME)
@Target ( ElementType. METHOD)
public @interface MyAnnotation {
String username ( ) ;
String password ( ) ;
}
package com. bjpowernode. java. annotation6;
import java. lang. reflect. Method;
public class MyAnnotationTest {
@MyAnnotation ( username = "admin" , password = "456456" )
public void doSome ( ) {
}
public static void main ( String[ ] args) throws Exception{
Class c = Class. forName ( "com.bjpowernode.java.annotation6.MyAnnotationTest" ) ;
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 ( ) ) ;
}
}
}
8>注解在开发中的作用
需求:
假设有这样一个注解,叫做:@Id
这个注解只能出现在类上面,当这个类上有这个注解的时候,
要求这个类中必须有一个int类型的id属性。如果没有这个属性
就报异常。如果有这个属性则正常执行!
package com. bjpowernode. java. annotation7;
import java. lang. annotation. ElementType;
import java. lang. annotation. Retention;
import java. lang. annotation. RetentionPolicy;
import java. lang. annotation. Target;
@Target ( ElementType. TYPE)
@Retention ( RetentionPolicy. RUNTIME)
public @interface MustHasIdPropertyAnnotation {
}
package com. bjpowernode. java. annotation7;
public class HasNotIdPropertyException extends RuntimeException {
public HasNotIdPropertyException ( ) {
}
public HasNotIdPropertyException ( String s) {
super ( s) ;
}
}
package com. bjpowernode. java. annotation7;
import java. lang. reflect. Field;
public class Test {
public static void main ( String[ ] args) throws Exception{
Class userClass = Class. forName ( "com.bjpowernode.java.annotation7.User" ) ;
if ( userClass. isAnnotationPresent ( MustHasIdPropertyAnnotation. class ) ) {
Field[ ] fields = userClass. getDeclaredFields ( ) ;
boolean isOk = false ;
for ( Field field : fields) {
if ( "id" . equals ( field. getName ( ) ) && "int" . equals ( field. getType ( ) . getSimpleName ( ) ) ) {
isOk = true ;
break ;
}
}
if ( ! isOk) {
throw new HasNotIdPropertyException ( "被@MustHasIdPropertyAnnotation注解标注的类中必须要有一个int类型的id属性!" ) ;
}
}
}
}
package com. bjpowernode. java. annotation7;
@MustHasIdPropertyAnnotation
public class User {
int id;
String name;
String password;
}