动态代理

  • java.lang.reflect.Proxy
    • static Object newProxyInstance(ClaccLoader loader, Class<?>[ ]interfaces, InvocationHandler h)生成一个动态代理对象的方法
    • ClassLoader loader:当前要生成代理对象这个类的类加载器 字节码文件对象.getInterface() InvocationHandler:就是一个接口 方法的参数是接口 需要传入其实现类对象 匿名内部类
  • 方法
    • Object invoke(Object proxy,Method method,Object[ ] args)

注解

  • 定义
    • 注解也叫元数据,一种代码级别的说明.与类 接口 枚举是在同一个层次 可以声明在包 类 字段 方法 局部变量 方法参数等的前面 用来对这些元素进行说明 注释
  • 作用分类
    • 编写文档:通过代码里标识的注解生成文档[例如,生成文档doc文档]
    • 代码分析:通过代码里标识的注解对代码进行分析[例如,注解的反射]
    • 编译检查:通过代码里标识的注解让编译能够实现基本的编译检查[例如,Override]

      常见注解

  1. @author:用来标识作者名
  2. @version:用来标识对象的版本号,适用范围:文件 类 方法
  3. @Override:用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败

自定义注解

  • 定义格式

    • 元注解

      • public @interface 注解名称{

        1. 属性列表;<br /> }<br /> 注解本质上就是一个接口,该接口默认继承Annotation接口
  • public @interface MyAnno extends

     java.lang.annotation.Annotation { }<br />              任何一个注解 都默认的继承Annotation接口
    

    注解的属性

  1. 属性的作用
    • 可以让用户在使用注解时传递参数,让注解的功能更加强大
  2. 属性的格式
    • 格式1:数据类型 属性名();
    • 格式2:数据类型 属性名()default默认值
  3. 属性定义示例

    public @interface Student{
    String name();姓名
    int age() default 18;//年龄
    String gender()default"男";//性别}
    //该注解就有了三个属性:name,age,gender
    
  4. 属性使用的数据类型

    • 八种基本数据类型

           (int,float,boolean,byte,double,char,long,short)
      
    • String类型, Class类型,枚举类型,注解类型

    • 以上所有类型的一维数组

使用自定义注解

在程序中使用(解析)注解的步骤(获取注解中定义的属性值):

  1. 获取注解定义的位置的对象 (Class,Method,Field)
  2. 获取指定的注解getAnnotation(Class)
  3. 调用注解中的抽象方法获取配置的属性值

使用格式:
@注解名(属性名=属性值,属性名=属性值,属性名=属性值…)

定义注解

  1. 定义一个注解:Book
    • 包含属性:String value()书名
    • 包含属性:double price()结构,默认值为100
    • 包含属性:String[] authors()多位作者

2.代码实现

public @interface Book{
//书名
String value()};
//价格
double price()default 100;
//多位作者
String[]authors();

使用注解

public class BookShelf{
@Book(value='西游记',price=998),authors={
"吴承恩","白求恩"})
    public void showBook(){
}
}

使用注意事项

  • 如果属性有默认值,则使用注解的时候,这个属性可以不用赋值
  • 如果属性没有默认值,那么在使用注解时一定要给属性赋值

特殊属性value

  1. 当注解中只有一个属性且名称是value,在使用注解时给value属性赋值可以直接给属性值,无论value是单值

    元素还是数组类型

    public @interface Book{
    String value();
    }
    public class BookShelf{
    @Book("西游记")
    public void showBook(){
    }
    }
    或
    public class BookShelf{
    @Book(value="西游记")
    public void showBook(){
    }
    }
    
  2. 如果注解中除了value属性还有其他属性,且至少有一个属性没有默认值,则在使用注解给属性赋值时,values属性名不能省略

    public @interface Book{
    Strng value();
    double price() default 100;
    String[]authors();
    }
    //使用Book注解:正确方式
    @Book(value="红楼梦",authors="曹雪芹")
    public class BookShelf{
    @Book(value="西游记",authors={"吴承恩","白求恩"})
     public void showBook(){
     }
    }
    //使用Book注解:错误方式
    public class BookShelf{
    @Book("西游记",authors={"吴承恩","白求恩"})
     public void showBook(){
     }
    }
    //此时value属性名不能省略了