# 反射和注解学习代码 **Repository Path**: longzhiquan/reflection ## Basic Information - **Project Name**: 反射和注解学习代码 - **Description**: No description available - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2020-04-26 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 反射和注解 ## 注解 Annotation ### 1. 内置注解 - @Override: 重写超类中的另一个方法 - @Deprecated: 不鼓励程序员用的方法 - @SuppressWarnings: 抑制编译时的警告信息 - @SuppressWarnings("all") - @SuppressWarnings("unchecked") ### 2. 元注解 解释其他注解的注解 - @Target: 描述注解的适用范围 - @Retention: 描述注解的生命周期 - @Document: 说明注解被包含在javadoc中 - @Inherited: 说明子类可以继承父类中的该注解 ```java import java.lang.annotation.*; //测试元注解 public class Test01 { public void test(){ } } //在方法上有效,在类上有效 @Target(value = {ElementType.METHOD, ElementType.TYPE}) //在运行时有效 //runtime>class>source @Retention(value = RetentionPolicy.RUNTIME) //将注解生成在javadoc中 @Documented //子类可以继承父类注解 @Inherited @interface MyAnnotation{ } ``` ### 3. 自定义注解 ```java import java.lang.annotation.*; public class Test02 { //如果没有默认值,我们就必须给注解赋值 @MyAnnotation2(name="hou", schoolds = {"大学"}) public void test(){ } //如果只有一个参数用value命名,可以省略value @MyAnnotation3("hou") public void test1(){ } } @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ //注解参数:参数类型+参数名()默认值是空 String name() default ""; int age() default 0; int id() default -1; //如果默认值是-1,代表不存在 String[] schoolds(); } @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3{ String value(); } ``` ## 反射 reflection ### 1. 概述 反射机制允许程序在执行期间借助于Rflection API取得任何类的内部消息,并能直接操纵任意对象的内部属性及方法。 Class c = Class.forName("java.lang.String") 加载完类之后,在堆内存的方法区中就产生一个Class类型的对象 **正常方式:** 1. 引入需要的包 2. 通过new实例化 3. 去的实例化对象 **反射方式:** 1. 实例化对象 2. getClass()方法 3. 得到完成的”包类“名称 ### 2. 反射对象 ```java package hou; public class Test03 { public static void main(String[] args) throws ClassNotFoundException { //通过反射获得class对象 Class c1 = Class.forName("hou.User"); System.out.println(c1); //hashcode一样 Class c2 = Class.forName("hou.User"); Class c3 = Class.forName("hou.User"); Class c4 = Class.forName("hou.User"); } } class User{ private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } ``` 三种方法: ```java package hou; public class Test04 { public static void main(String[] args) throws ClassNotFoundException { People people = new Student(); System.out.println(people); //通过对象获得 Class c1 = people.getClass(); //forname获得 Class c2 = Class.forName("hou.People"); //通过类名.class获得 Class c3 = Student.class; //hashcode一样 //获得父类 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class People{ private String name; public People() { } public People(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "People{" + "name='" + name + '\'' + '}'; } } class Student extends People{ public Student() { super("学生"); } } class Teacher extends People{ public Teacher() { super("Teacher"); } } ``` 所有类型对象 ```java public class Test05 { public static void main(String[] args) { Class c1 = Object.class; Class c2 = Comparable.class; Class c3 = String[].class; Class c4 = int[][].class; Class c5 = Override.class; //注解 Class c6 = ElementType.class; //枚举 Class c7 = Integer.class; //基本数据类型 Class c8 = void.class; //void Class c9 = Class.class; //Class } } ``` ### 3. 类加载理解 ```java public class Test06 { public static void main(String[] args) { A a = new A(); System.out.println(A.m); } } class A{ static{ System.out.println("A静态代码块"); m = 300; } static int m = 200; public A(){ System.out.println("A无参"); } } ``` output ```console A静态代码块 A无参 200 ``` ### 4. 类的初始化 ```java package hou; public class Test07 { static { System.out.println("Main"); } public static void main(String[] args) throws ClassNotFoundException { //主动引用 // Son son = new Son(); //反射也会产生主动引用 // Class.forName("hou.Son"); // Main // father // Son //不会产生引用 // System.out.println(Son.f); // Main // father // 0 // Son[] sons = new Son[5]; // Main System.out.println(Son.n); // Main // 1 } } class Father{ static int f = 0; static { System.out.println("father"); } } class Son extends Father{ static{ System.out.println("Son"); m = 300; } static int m = 200; static final int n = 1; } ``` ### 5. 类的加载器 ```java public class Test08 { public static void main(String[] args) throws ClassNotFoundException { //获取系统类加载器 ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println(classLoader); //获取系统加载器的父类-->扩展加载器 ClassLoader classLoader1 = classLoader.getParent(); System.out.println(classLoader1); //获取扩展加载器的父类-->根加载器 ClassLoader classLoader2 = classLoader1.getParent(); System.out.println(classLoader2); //系统类加载器 System.out.println(Class.forName("hou.Test08").getClassLoader()); //根加载器 System.out.println(Class.forName("java.lang.Object").getClassLoader()); } } ``` ### 6. 获取运行时的结构 ```java package hou; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test09 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("hou.User"); System.out.println(c1.getName()); //包名+类名 System.out.println(c1.getSimpleName()); //类名 //获得所有属性 Field[] fields = c1.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } //获得public方法 Method[] methods = c1.getMethods(); for (Method method : methods) { System.out.println(method); } //获得指令属性 Field name = c1.getDeclaredField("name"); System.out.println(name); //获得指定方法 Method getname = c1.getMethod("getName", null); Method setname = c1.getMethod("setName", String.class); System.out.println(getname); System.out.println(setname); //获得指定的构造器 Constructor[] constructors = c1.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } //获得指令构造器 Constructor constructor = c1.getConstructor(String.class, int.class); System.out.println(constructor); } } ``` ### 7. 动态创建对象 ```java package hou; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test10 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class c1 = Class.forName("hou.User"); User use = (User) c1.newInstance(); System.out.println(use); Constructor constructor = c1.getConstructor(String.class, int.class); User user2 = (User) constructor.newInstance("hou", 18); System.out.println(user2); //通过反射调用方法 User user3 = (User) c1.newInstance(); Method setname = c1.getMethod("setName", String.class); setname.invoke(user3, "dong"); System.out.println(user3.getName()); //获取反射操作属性 User user4 = (User) c1.newInstance(); Field field = c1.getDeclaredField("age"); field.setAccessible(true); field.set(user4, 100); System.out.println(user4.getAge()); } } ``` ### 8. 反射操作泛型 通过反射获取泛型 ```java package hou; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class Test11 { public void test1(Map map){ System.out.println("test1"); } public List test2(){ return null; } public static void main(String[] args) throws NoSuchMethodException { Method method1 = Test11.class.getMethod("test1", Map.class); Type[] genericParameterTypes = method1.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println(genericParameterType); if(genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } Method method2 = Test11.class.getMethod("test2", null); Type genericReturnType = method2.getGenericReturnType(); if(genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } } ``` ### 9. 反射操作注解 ```java package hou; import java.lang.annotation.*; import java.lang.reflect.Field; //反射操作注解 public class Test12 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("hou.Student2"); Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //获得注解的值 Table annotation = (Table) c1.getAnnotation(Table.class); String value = annotation.value(); System.out.println(value); Field name = c1.getDeclaredField("name"); MyField mf = name.getAnnotation(MyField.class); System.out.println(mf.columnName()); System.out.println(mf.length()); System.out.println(mf.type()); } } @Table("hou") class Student2{ @MyField(columnName = "dbname", type = "String", length = 10) private String name; @MyField(columnName = "dbid", type = "int", length = 2) private int id; @MyField(columnName = "dbage", type = "int", length = 2) private int age; public Student2() { } public Student2(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student2{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } } //类名注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Table{ String value(); } //属性注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface MyField{ String columnName(); String type(); int length(); } ```