注解(Annotation)是从JDK5.0引入的新技术
Annotation作用:注解(Annotation)可以被其他程序如编译器等读取
Annotation格式:@"注释名",当然可以添加一些参数值(形如:@Retention(RetentionPolicy.RUNTIME))
它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
Annotation注解可以通过反射去读取
注解的定义 内置注解@Override 定义在java.lang.Override中,此注释只适用于修辞方法,表示声明一个方法打算重写超类中的另一个方法。
@Deprecated定义在java.lang.Deprecated中,此注释只适用于修辞方法,属性,类,表示不支持使用这样的元素
@SupperWarnings定义在java.lang.SupperWarnings中,用来抑制编译告警时的警告信息,需要添加一个参数才能正确使用
元注解元注解的作用就是负责注解其他注解,java定义了4个标准的meta-annotation类型:@Target/@Retention/@Document/@Inherited
元注解中重点为@Target和@Retention
@Target:用于描述注解的作用范围(比如作用在某个类或某个方法)
@Retention:描述注解的生命周期,对于反射就是可以在什么时候获取该注解(SOURCE<CLASS<RUNTIME)
自定义注解使用@interface可以自定义注解。
@interface 注解名{ //自定义的注解内容 //如果参数只有一个值,建议写value String value(); }例子
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class TestAnnotationDemo3 { //测试自定义注解 @MyAnnotation2("qifei") @MyAnnotation(name = "wuhu", id = 10) public void test(){ System.out.println("test"); } } @Target(value = {ElementType.TYPE,ElementType.METHOD}) //作用于 方法和类 @Retention(RetentionPolicy.RUNTIME) //作用于 运行时 @interface MyAnnotation{ //定义参数 String[] name() default ""; //参数默认为空,参数名为name int id(); } @Target(value = {ElementType.TYPE,ElementType.METHOD}) //作用于 方法和类 @Retention(RetentionPolicy.RUNTIME) //作用于 运行时 @interface MyAnnotation2{ //如果参数只有一个值,建议写value String value(); } 反射(Reflection)机制Java反射(Reflection)是Java非常重要的动态特性,通过使用反射我们不仅可以获取到任何类的成员方法、成员变量、构造方法等信息,还可以动态创建Java类实例、调用任意的类方法、修改任意的类成员变量值等。注解和反射是各种java web框架的底层实现机制与灵魂。
Class类反射首先要用到的就是Class类,Class类是一个描述类的类,但是Class本身也是一个类,一个在内存中加载的类在JVM中只会有一个对应的Class的实例话对象,通过Class可以完整的得到一个类中所有被加载的结构。Class类就是反射的根源
获取Class类实例1、已知具体的类,通过类的class属性获取
Class c = Object.class;2、已知某个类的实例,通过调用getClass()方法获取class对象
Person person = new Person(); Class c = person.getClass();3、已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取class对象
Class c = Class.forName("com.reflection.demmo");4、基本内置类型的包装类的Type属性获取class对象
Class c = Integer.TYPE;例子:
//测试class类的创建方式 public class ReflactionDemo02 { public static void main(String[] args) throws ClassNotFoundException { Person student = new Student(); System.out.println("这个人是:" + student.name); //获取Student类的class实例对象 //1、通过getClass() 获得 Class c1 = student.getClass(); System.out.println(c1.hashCode()); //2、通过Class类的forName() 获得 Class c2 = Class.forName("com.reflaction.Student"); System.out.println(c2.hashCode()); //3、通过student类的class属性获得 Class c3 = Student.class; System.out.println(c3.hashCode()); //4、基本内置类型的包装类的Type属性 Class c4 = Integer.TYPE; System.out.println(c4.hashCode()); //获得父类类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person{ String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student(){ this.name = "学生"; } } class Teacher extends Person{ public Teacher(){ this.name = "老师"; } } 这个人是:学生 1627674070 1627674070 1627674070 1360875712 class com.reflaction.Person 具有Class实例对象的数据类型 //所有类型的class对象 public class ReflactionDemo03 { public static void main(String[] args) { Class c1 = Object.class; //类 Class c2 = Runnable.class; //接口 Class c3 = String[].class; //一维数组 Class c4 = String[][].class; //二维数组 Class c5 = Override.class; //注解 Class c6 = ElementType.class; //枚举 Class c7 = Integer.class; //基本数据类型包装类 Class c8 = void.class; //void Class c9 = Class.class; //Class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); } } class java.lang.Object interface java.lang.Runnable class [Ljava.lang.String; class [[Ljava.lang.String; interface java.lang.Override class java.lang.annotation.ElementType class java.lang.Integer void class java.lang.Class 反射获取类运行时的完整结构 Field() Field[] fields = c1.getFields(); //getFields 只能找到pubilc属性 fields = c1.getDeclaredFields(); //getDeclaredFields 可以找到所有属性 for (Field field : fields) { System.out.println(field); } Method()getMethods()获得本类和继承类的所有public方法
getDeclaredMethods()获取本类的所有方法