java学习笔记:注解Annotation

java学习笔记:注解Annotation

 

注解Annotation
----
1.注解的概念:
注解也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、抽象类是在同一个层次,同属于数据类型。
注释是给开发人员阅读的,注解是给计算机提供相应信息的。

2.作用:
(1)编译检查:通过代码里标识的注解,让编译器能够实现基本的编译检查。例如:
@Override
Person{ void getSalray(){} }
(2)充当配置文件
如果配置的信息不会发生频繁的修改,采用注解的配置,例如:
@WebServlet("/ServletDemo01")
如果配置的信息可能会发生频繁的修改,采用web.xml/properties的配置。例如:
mysql的用户名和密码不推荐采用注解配置形式
@MyAnn(name="user",pass="1234")
class JDBCUtils{}
(3)javadoc编写文档:辅助生成帮助文档。例如:
@author  @see  @since
  -encoding utf-8 -charset utf-8

3.JDK的三种注解
@Override :当前方法是重写父类的方法/重写接口的方法
@Deprecated当前方法是过时的方法
@SuppressWarnings("all")告诉编译器,当前类内不要报任何警告信息
(1)注释的位置:注解可以加载在变量上,方法上,类上
(2)注解的形式
*_没有任何成员的注解
@Override  
*_有多个成员的注解
@SuppressWarnings({ "rawtypes", "unused" })
(3)注解的作用范围
1_源码上有效:eg:String类中@author ,将java源码转换为帮助文档期间起作用
2_编译期间有效:eg: override deprecated SuppressWarnings("all")
3_运行期间有效

4.定义注解(理解并代码实现)
1_定义没有属性成员注解:
public @interface MyAnno01{}
2_定义有1个属性成员注解
public @interface MyAnno02{
    public String value();
}
3_定义有多个属性成员注解
public @interface 注解名称{
public 类型名称 属性名称() default 默认值;
public 类型名称 属性名称() default 默认值;
//注解支持的类型:基本类型(4类8种),String,Class(字节码类型),
//annotaion(注解),enumeration(枚举),以上类型支持的一维数组类型
}
public @interface MyAnno03 {
    //定义多个属性的注解
    public String username() default "tom";
    //public Father f();
    //Invalid type Father for the annotation attribute MyAnno03.f; 
    //only primitive type, String, Class, annotation, enumeration are permitted 
    //or 1-dimensional arrays thereof
    //非法的注解属性f,仅仅是原始(基本)类型,String ,Class,annotation,
//枚举类型是被允许的或者以上的一维数组类型是允许的
//注解支持的类型:基本类型(4类8种),String,Class(字节码类型),
//annotaion(注解),enumeration(枚举),以上类型支持的一维数组类型
    public int age();
    public double weight() default 2342.23;
    public Class clazz();
    public MyAnno01 my01();    
}

5_使用自定义注解(理解实现代码)
没有任何属性的注解
有1个属性的注解
有多个属性的注解
@MyAnno01
@MyAnno02(value="testtest")
@MyAnno03(age=18,clazz=String.class,username="tom",weight=23.23,my01=@MyAnno01)
public class MyClass {}

注意:如果注解只有一个属性,而且这个属性的名称是value,那么在使用这个注解的使用,可以采用如下形式: 直接为属性赋值,不需要采用key=”vaule”的形式
@MyAnno02("testtest")
public class MyClass02 {}

注解的作用:实现配置
注意:如果配置信息不经常修改,用注解形式。如果配置的信息需要频繁修改,推荐properties或者XML


6.通过反射获取方法上的注解信息(理解并实现代码)
1_理解反射的本质
反射本质上是在做什么事情?
前提:实现JAVA代码,将JAVA编译为class文件.编译完之后class文件在硬盘上,
当需要执行class文件中的代码时,JDK内置程序(类加载器):
通过IO流的形式将字节码的内容读取到内存. 字节码在内存中形成的对象就是Class对象
通过Class对象创建对象,获取字节码对象上所有的方法,调用这些方法使其执行

类加载器:JDK中内置的一类程序,这类程序专业用于将硬盘上的字节码文件加载到内存中.
类加载器有3种: 应用类加载器,扩展类加载,根类加载器

2_测试通过反射获取注解信息的API
常用方法:
boolean isAnnotationPresent(Class annotationClass) 判断当前对象上是否有指定类型的注解

3_JAVA中的元注解
元注解:用于修饰注解的注解
Jdk提供4种元注解
(1)@Retention 用于确定被修饰的自定义注解生命周期,确定自定义注解的生命周期的
可能取值:
  RentionPolicy.SOURCE,被修饰的注解只能用于源码中,字节码class没有。用途:提供给编译器使用
  RentionPolicy.CLASS 被修饰的注解只能存在于源代码或字节码中,运行时内存中没有。用途:JVM java虚拟机使用
  RentionPolicy.RUNTIME 被修饰的注解存在于源码,字节码,内存(运行时)。用途:取代XML充当配置信息
(2)@Target 用于确定被修饰自定义注解使用位置
可能取值
  ElementType.TYPE  修饰类,接口
  ElementType.CONSTRUCTOR  修饰构造函数
  ElementType.METHOD 修饰方法
  ElementType.FIELD 修饰字段
(3)@Documented 使用javadoc生成api文档是,是否包含此注解(了解)

代码如下:
//file name: MyAnno.java
package com.study.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface MyAnno {
}

//file name: AAA.java
package com.study.annotation;

public class AAA {
    @MyAnno
    public void test01(){}

    @MyAnno
    public void test02(){}

    public void test03(){}
}

//file name: TestMyAnnotationRead.java
package com.study.annotation;

import java.lang.reflect.Method;

public class TestMyAnnotationRead {
    public static void main(String[] args) {
        Class clazz = AAA.class;
        Method[] methods = clazz.getMethods();
        for (Method m : methods) {
            if(m.isAnnotationPresent(MyAnno.class)){
                System.out.println(m.getName());
            }
        }
    }
}


7.案例_模拟Junit(动手实现)
*_案例分析
1_首先需要编写自定义注解@MyTest,并添加元注解,
保证自定义注解只能修饰方法,且在运行时可以获得。
2_其次编写目标类(测试类),然后给目标方法(测试方法)使用@MyTest注解
3_最后编写测试类,使用main方法模拟Junit的右键运行。

*_案例代码
步骤1:编写自定义注解类@MyTest
package com.study.annotation;

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 MyTest{
    
}

步骤2:编写目标类AnnotationDemo
package com.study.annotation;

public class AnnotationDemo {
    @MyTest
    public void demo01(){
        System.out.println("demo01 执行了……");
    }

    @MyTest
    public void demo02(){
        System.out.println("demo02 执行了……");
    }

    public void demo03(){
        System.out.println("demo03 执行了……");
    }
}

步骤3:编写测试方法
package com.study.annotation;

import java.lang.reflect.Method;

public class App {
    public static void main(String[] args) {
        try{
            //1.1 反射:获得类的字节码对象.Class
            Class clazz = AnnotationDemo.class;
            //1.2 获得实例对象
            Object obj = clazz.newInstance();

            //2 获得目标类所有的方法
            Method[] allMethod = clazz.getMethods();
            //3 遍历所有的方法
            for (Method method : allMethod) {
                //3.1 判断方法是否有MyTest注解
                boolean flag = method.isAnnotationPresent(MyTest.class);
                if(flag){
                    //4 如果有注解,运行指定的类
                    method.invoke(obj, args);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

====

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值