注解
1.注解概述
注解主要起到标识作用,是JDK5.0提出的,Java增加对元数据的支持,也就是Annotation(注解)
什么是元数据?
元数据是用来描述数据的数据,通俗一点来说,就是描述代码间的关系,或者代码与其他资源(数据库)之间的内在联系的数据。
举例:
- 对于struts来说,元数据就是struts-config.xml;
- 对于hibernate来说就是hbm文件;
如何创建元数据?
JDK5.0出来后,Java语言提出了四种类型:类(class)、枚举(enum)、接口(interface)和注解(@interface),他们处在同一个级别。Java就是通过注解来表示元数据的。
2.三种基本注解
@Override:限定重写父类的方法,该注解只能用于方法;
@Deprecated:用于表示某个程序中的元素(类、方法等)已经过时;
@SuppressWarning:抑制编译器警告;
使用案例
public interface People {
public String name();
public int age();
//如果work()方法正在使用,但又想表示它,则使用Deprecated标记
@Deprecated
public void work();
}
public class TestAnnotation implements People{
@Override
public int age() { return 0; }
@Override
public String name() { return null; }
@Override
public void work() { }
}
public class TestAnno {
@SuppressWarnings("all")
public static void main(String[] args) {
//利用多态的原则,接口new一个实现类
// People people = new TestAnnotation();
// people.work();
//上面代码将会提示work方法已经过时
//如果方法已经过时却又想要使用它,则使用注解@SuppressWarnings("all"),即可去除所有警告
People people = new TestAnnotation();
people.work();
}
}
3.注解分类
(1) 按照运行机制划分
-
源码注解:只在源码中存在,编译成
.class
文件就不存在了; -
编译时注解:在源码和
.class
文件中都存在,像@Override
、@Deprecated
、@SuppressWarning
,都属于编译时注解; -
运行时注解:在运行阶段起作用,甚至会影响运行逻辑的注解。像
@Autowired
自动注入属于运行时注解,会在运行阶段将你的成员变量自动的注入进来;
(2) 按照来源划分
- 按照来源划分;
- 来自第三方的注解;
- 自定义的注解;
(3) 元注解
- 元注解就是给注解进行注解,可以理解为注解的注解;
- @Retention:说明该注解的生命周期
- @RententionPolicy. CLASS:指注解只保留一个 class文件中
- @RententionPolicy. SOURCE:指定注解只保留在一个源文件中
- RententionPolicy. RUNTIME:指定注解可以保留在程序运行期间
- @Documented:文档注解
- @Inherited:被他修饰的注解将具有继承性,如果某个类使用被该注解修饰的注解,则它的子类将自动具有该注解
- @Target:作用域
- ElementType.tye:说明该注解只能被声明在一个类前。
- ElementType. FIELD:说明该注解只能被声明在一个类的字段前。
- ElementType. METHOD:说明该注解只能被声明在一个类的方法前。
- ElementType. CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前
- ElementType. OCAL VARIABLE:说明该注解只能声明在一个局部变量前。
- ElementType, PARAMETER:说明该注解只能被声明在一个方法参数前。
- ElementType. ANNOTATION TYPE:说明该注解只能声明在一个注解类型前。
- ElementType. PACKAGE:说明该注解只能声明在一个包名前。
- @Retention:说明该注解的生命周期
4.自定义注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
/*
* 1.成员类型受限,合法类型:基本数据类型,String,Class,Annotation等
* 2.如果注解只有一个成员,则成员名必须为value(),在使用时候可以忽略成员名和赋值号(=)
* 3.注解类可以没有成员,没有成员的注解称为标识注解
*
* 注解按照是否有值分为三类:标记注解、单值注解、完全注解
*/
// String desc();//在注解里面只是一个成员变量
// String author();
// int age() default 18;//成员变量可以使用default指定一个默认值
String value() default "小二 ";
}
public class TestAnnotation {
//如果注解没有值,就是标记注解,只起到标记的作用
//@Description
public void method1() {
// TODO Auto-generated method stub
}
//完全注解,注解中有多个值
//@Description(author="xxx",desc="asc",age=19)
public void method2() {
// TODO Auto-generated method stub
}
//单值注解
//@Description("三")
public void method3() {
// TODO Auto-generated method stub
}
//Test注解,注解执行方法,可以让main中有多个执行方法
@Test
public void test1(){}
@Test
public void test2(){}
}
自定义注解实例
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
public class Color {
@MyAnnotation("red")
public void red(){
System.out.println("执行red方法");
}
@MyAnnotation("blue")
public void blue(){
System.out.println("执行blue方法");
}
}
import java.lang.reflect.InvocationTargetException;
public class TestColor {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
//反射,通过反射动态的执行方法
MethodInvoke.invoke("blue");
}
}
public class MethodInvoke {
public static void invoke(String string) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
//获取运行时的类
Class class1 = Color.class;
//获取本类的所有方法
Method[] methods = class1.getDeclaredMethods();
for (Method method : methods) {
//判断方法上是否有注解
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
String value = annotation.value();
if (string.equals(value)) {
method.invoke(class1.newInstance());
}
}
}
}
}