注解简介
注解:称为java标注,被解析到应用程序中
java.long.Annotation:
java所有注解的公共接口,父类Annotation
注解本质就是一个接口----里面的方法名---->称为注解"属性"
jdk常见注解
- @override
标记方法成员方法实现(重写)接口方法 - @SupperssWarnings
抑制警告: 项目部署上线,所有的类里不能出现黄色警告 - @SupperssWarnings(value=“all”)
压制所有警告,value可以省略不写 - @Deprecated
标记这个方法已经过时 - @FunctionalTnterface
标记接口为函数式接口(接口中有且仅有一个抽象方法)
枚举
Class Enum<E extends Enum>
该类只能被子类实例化,子类会继承其方法.就是类型E是Enum的子类.而该类的compareTo方法参数就是类型E,既子类.
举例:
public enum MyEnum {
LEFT ,//左
RIGHT ;//右
}
- 枚举是一种特殊的数据类型,既是一种Class类型却又比类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁,安全以及便捷性.
- 创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类(java.lang.Enum是一个抽象类)。
- 枚举类型符合通用模式Class Enum>,而E表示枚举类型的名称。
- 枚举类型的每一个值都映射到protected Enum(String name,int ordinal)构造函数中,在这里,每个值的名称都转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
元注解以及自定义注解
元注解
内置注解依赖一些"元注解"
- @Target:标记指定的注解使用的范围
ElementType[] value();
value属性的返回值,枚举类型的数组
ElementType: 说明@Target使用的范围
枚举:
TYPE 标记注解使用在类上或者接口上
FIELD 标记注解使用在成员变量上
METHOD 标记这个注解可以在方法上用
PARAMTER 标记注解可以在形式参数上使用 - @Retention: 标记当前注解能够在什么界别下使用
RetentionPolicy value();
value属性返回值枚举 RetentionPolicy
三个级别:
SOURCE 源代码编译阶段
CLASS 当前类接在阶段
RUNTIME 运行阶段 - @Documented
解析的时候保留一些文档注释
自定义注解
注解中的属性名(接口中的成员方法名)的返回值类型
- 基本数据类型
- 字符串类型
- 枚举类型
- 注解类型
- 以上格式的数组格式
创建两个类
public class Student {
public void love(){
System.out.println("爱学习,爱Java!");
}
}
public class Worker {
public void love(){
System.out.println("爱生活,爱工作...");
}
}
- 直接创建对象调用方法
public class Test {
public static void main(String[] args) throws Exception {
//当前需求不断变化,不断改动代码
Student s = new Student() ;
s.love();
Worker w = new Worker() ;
w.love();
需要不断的改动代码
- 通过读取配置文件调用方法
- 创建.properties的文件
className=com.qf.annotation_03.Worker
methodName=love - 测试类
//读取配置文件,解析配置文件中key对应value
InputStream inputStream = Test.class.getClassLoader().
getResourceAsStream("class.properties");
//创建属性集合列表
Properties prop = new Properties() ;
prop.load(inputStream) ;
//通过key获取value
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
//反射创建当前类实例
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
//获取成员方法Method类对象
Method method = clazz.getMethod(methodName);
method.invoke(obj) ;
直接改配置文件就行
- 自定义注解方式
- 创建注解类
@Target(ElementType.TYPE) //能用在类上
@Retention(RetentionPolicy.RUNTIME)//运行阶段用
public @interface MySelfAnno {
String className() ;//className属性
String methodName() ;//methodName属性
}
- 测试类
//在测试类名上标记一个注解
@MySelfAnno(className = "com.qf.annotation_03.Student",methodName = "love")
public class Test {
public static void main(String[] args) throws Exception {
//自定义注解,解析注解
//1)获取当前注解标记的这个类的字节码文件对象
Class clazz2 = Test.class ;
//2)通过Class字节码文件对象---->解析注解---获取注解(接口)---->实现类对象
//public <A extends Annotation> A getAnnotation(Class<A> annotationClass) :
// 参数里面说的注解的字节码文件对象
MySelfAnno mySelfAnno = (MySelfAnno)
clazz2.getAnnotation(MySelfAnno.class);//向下转型
/**
* MySelfAnno mySelfAnno = (MySelfAnno) clazz2.getAnnotation(MySelfAnno.class);
*
* 相当于
*
* 获取到了 class MySelfAnnoImpl implemtns MySelfAnno{
*
* String className() {
* return "com.qf.annotation_03.Worker"
* }
* String methodName() {
* return "love";
* }
* }
*/
String s1 = mySelfAnno.className(); //类的全限定名称
String s2 = mySelfAnno.methodName(); //方法名
//获取当前类的字节码文件对象
Class s1Clazz = Class.forName(s1) ;
//创建当前类实例
Object obj2 = s1Clazz.newInstance() ;
Method m = s1Clazz.getMethod(s2);//获取成员方法Method类对象
m.invoke(obj2) ;
}
}