注解和反射_2
p10-p17内容
1: 类的初始化
1 package Reflection; 2 3 import java.sql.Struct; 4 5 /** 6 * author liulei 7 * data 5.22 8 * since 1.8 9 * version 1.0 10 * Description 类的初始化 11 */ 12 public class Test04 { 13 public static void main(String[] args) throws ClassNotFoundException { 14 //1主动引用 15 Son s = new Son();//new 一个实例 16 Class.forName("Reflection.Son");//反射会主动引用 17 //2 不会产生引用 18 System.out.println(Son.b);//子类引用父类的方法 19 Son[] s1 = new Son[5];//通过数组定义类引用 20 } 21 } 22 class Father{ 23 static int b = 2; 24 static { 25 System.out.println("父类被加载"); 26 } 27 } 28 class Son extends Father{ 29 static { 30 System.out.println("子类被加载"); 31 } 32 static int m = 100; 33 static final int n = 1; 34 }
2:类加载器的作用
1 package Reflection; 2 3 /** 4 * author liulei 5 * data 5.22 6 * since 1.8 7 * version 1.0 8 * Description 三种类加载器 9 */ 10 public class Test5 { 11 12 //双亲委派机制:java.lang.String-->,多重检测,当自己写的类和跟类(rt.jar)相同时,自己写的类无效 13 public static void main(String[] args) throws ClassNotFoundException { 14 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();//系统类加载器 15 System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2 16 ClassLoader parent = systemClassLoader.getParent();//扩展类加载器(是系统类加器的子集或父亲) 17 System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@1b6d3586 18 ClassLoader parent1 = parent.getParent();//跟加载器(扩展类加载器的子集或父亲) 19 System.out.println(parent1);//null,因为不可访问所以为null 20 //测试当前类是那个加载器加载的 21 ClassLoader classLoader = Class.forName("Reflection.Test5").getClassLoader();//sun.misc.Launcher$AppClassLoader@18b4aac2 22 System.out.println(classLoader); 23 //获取jdk内置的类是谁加载的 24 ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader(); 25 System.out.println(classLoader1);//null 26 //如何获得系统类加载器可以加载的路径 27 System.out.println(System.getProperty("java.class.path")); 28 /* 29 D:\Eclipse\JDK\jre\lib\charsets.jar; 30 D:\Eclipse\JDK\jre\lib\deploy.jar; 31 D:\Eclipse\JDK\jre\lib\ext\access-bridge-64.jar; 32 D:\Eclipse\JDK\jre\lib\ext\cldrdata.jar; 33 D:\Eclipse\JDK\jre\lib\ext\dnsns.jar; 34 D:\Eclipse\JDK\jre\lib\ext\jaccess.jar; 35 D:\Eclipse\JDK\jre\lib\ext\jfxrt.jar; 36 D:\Eclipse\JDK\jre\lib\ext\localedata.jar; 37 D:\Eclipse\JDK\jre\lib\ext\nashorn.jar; 38 D:\Eclipse\JDK\jre\lib\ext\sunec.jar; 39 D:\Eclipse\JDK\jre\lib\ext\sunjce_provider.jar; 40 D:\Eclipse\JDK\jre\lib\ext\sunmscapi.jar; 41 D:\Eclipse\JDK\jre\lib\ext\sunpkcs11.jar; 42 D:\Eclipse\JDK\jre\lib\ext\zipfs.jar; 43 D:\Eclipse\JDK\jre\lib\javaws.jar; 44 D:\Eclipse\JDK\jre\lib\jce.jar; 45 D:\Eclipse\JDK\jre\lib\jfr.jar; 46 D:\Eclipse\JDK\jre\lib\jfxswt.jar; 47 D:\Eclipse\JDK\jre\lib\jsse.jar; 48 D:\Eclipse\JDK\jre\lib\management-agent.jar; 49 D:\Eclipse\JDK\jre\lib\plugin.jar; 50 D:\Eclipse\JDK\jre\lib\resources.jar; 51 D:\Eclipse\JDK\jre\lib\rt.jar; //java核心库 52 D:\Code\IDEA\Stage01\Demo03\out\production\Demo03;//自己的目录 53 D:\IDEA\IntelliJ IDEA Community Edition 2020.1.1\lib\idea_rt.jar 54 55 */ 56 } 57 }
自己写的类由引导类加载器(又称用户类加载器)加载的,jdk内置的类由跟加载器加载的(系统类加载器)
类加载器默默的完成类的加载,而我们只需显示使用获取类Class的几个方法就行,不需要关心classloader的工作。
3:如何获取类的完整结构
package Reflection; import javax.naming.Name; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * author liulei * data * since 1.8 * version 1.0 * Description 获取运行时类的完整结构 */ public class Test6 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class aClass = Class.forName("Reflection.user"); System.out.println(aClass.getName());//报名+类名 System.out.println(aClass.getSimpleName());//类名 Field[] fields = aClass.getFields();//获取public的字段 System.out.println("===================================字段"); Field[] declaredFields = aClass.getDeclaredFields();//可以获取私有字段 for(Field field:fields){ System.out.println(field);//无输出 } for (Field field1:declaredFields){ System.out.println(field1);//有输出 /* java.lang.String Reflection.user.name int Reflection.user.id int Reflection.user.age */ } //获得指定属性的值 Field name = aClass.getDeclaredField("name"); //获取方法 System.out.println("===============================方法"); Method[] declaredMethods = aClass.getMethods();//获取本类和父类的所有方法 for(Method m:declaredMethods){ System.out.println(m); } Method[] declaredMethods1 = aClass.getDeclaredMethods();//获取本类的所有方法 for(Method m1:declaredMethods1){ System.out.println(m1); } //获取指定属性的方法 Method getName = aClass.getDeclaredMethod("getName", null); Method setName = aClass.getDeclaredMethod("setName", String.class); System.out.println(getName); System.out.println(setName); //获取构造器 System.out.println("=======================================构造器"); Constructor[] constructors = aClass.getConstructors(); for (Constructor c:constructors){ System.out.println(c); } Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class, int.class); System.out.println("指定"+declaredConstructor); } } class user{ private String name; private int id; private int age; public user(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public user() { } public String getName() { return name; } public int getId() { return id; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setId(int id) { this.id = id; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "user{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } }
4:利用Class对象创建类的对象操作属性,方法,泛型,注解等
1 package Reflection; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 8 /** 9 * author liulei 10 * data 5.22 11 * since 1.8 12 * version 1.0 13 * Description 用Class创建对象操作类方法和属性 14 */ 15 public class Test7 { 16 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { 17 Class<?> aClass = Class.forName("Reflection.user"); 18 user instance =(user)aClass.newInstance();//本质是调用不参构造器创建对象 19 System.out.println(instance); 20 //通过构造器创建对象 21 Constructor constructor = aClass.getDeclaredConstructor(String.class,int.class,int.class); 22 user haha = (user)constructor.newInstance("haha", 12, 12); 23 System.out.println(haha); 24 //通过对象获取一个方法 25 Method setName = aClass.getDeclaredMethod("setName", String.class); 26 setName.invoke(instance,"我的名字");//激活该方法 27 System.out.println(instance.getName()); 28 //获取对象一个属性 29 Field name = aClass.getDeclaredField("name"); 30 name.setAccessible(true);//不能直接操作私有属性,需要改代码设置关闭安全监测 31 name.set(instance,"我的名字"); 32 System.out.println(instance.getName()); 33 34 35 } 36 }
使用反射是低效率的,
1 package Reflection; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 7 /** 8 * author liulei 9 * data 5.22 10 * since 1.8 11 * version 1.0 12 * Description 效率分析 13 */ 14 public class Test8 { 15 //普通方法调用 16 public static void demo01(){ 17 user u = new user(); 18 long startTime = System.currentTimeMillis(); 19 for (int i = 0; i <= 100000000; i++){ 20 u.getName(); 21 } 22 long endtime = System.currentTimeMillis(); 23 System.out.println(endtime-startTime); 24 } 25 //反射方法调用 26 public static void demo02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { 27 user u = new user(); 28 Class aClass = Class.forName("Reflection.user"); 29 Method getName = aClass.getDeclaredMethod("getName"); 30 long startTime = System.currentTimeMillis(); 31 for (int i = 0; i <= 100000000; i++){ 32 getName.invoke(u,null); 33 } 34 long endtime = System.currentTimeMillis(); 35 System.out.println(endtime-startTime); 36 } 37 //反射方法调用,关闭监测 38 public static void demo03() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { 39 user u = new user(); 40 Class aClass = Class.forName("Reflection.user"); 41 Method getName = aClass.getDeclaredMethod("getName"); 42 getName.setAccessible(true); 43 long startTime = System.currentTimeMillis(); 44 for (int i = 0; i <= 100000000; i++){ 45 getName.invoke(u,null); 46 } 47 long endtime = System.currentTimeMillis(); 48 System.out.println(endtime-startTime); 49 50 } 51 52 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { 53 demo01();//3 54 demo02();//286 55 demo03();//155 56 //所以反射应用耗时较长,尽量不适用不必要的反射,同时需要关闭监测时尽量关闭监测可以加快时间 57 } 58 59 }
通过反射获取操作泛型
1 package Reflection; 2 3 import java.lang.reflect.Method; 4 import java.lang.reflect.ParameterizedType; 5 import java.lang.reflect.Type; 6 import java.util.List; 7 import java.util.Map; 8 9 /** 10 * author liulei 11 * data 12 * since 1.8 13 * version 1.0 14 * Description 通过反射获取泛型 15 */ 16 public class Test9 { 17 public void test01(Map<String,user> map, List<user> list){ 18 System.out.println("test01"); 19 } 20 public Map<String,user> test02(){ 21 System.out.println("test02"); 22 return null; 23 } 24 25 public static void main(String[] args) throws NoSuchMethodException { 26 Method test01 = Test9.class.getMethod("test01", Map.class, List.class); 27 Type[] genericParameterType = test01.getGenericParameterTypes(); 28 for(Type gpt:genericParameterType){ 29 System.out.println("gpt"+gpt); 30 if(gpt instanceof ParameterizedType){ 31 Type[] actualTypeArguments = ((ParameterizedType) gpt).getActualTypeArguments(); 32 for (Type p:actualTypeArguments){ 33 System.out.println(actualTypeArguments); 34 } 35 } 36 } 37 Method test02 = Test9.class.getMethod("test02", null); 38 Type genericParameterTypess = test02.getGenericReturnType(); 39 if(genericParameterTypess instanceof ParameterizedType){ 40 Type[] actualTypeArguments = ((ParameterizedType) genericParameterTypess).getActualTypeArguments(); 41 for (Type act:actualTypeArguments){ 42 System.out.println(actualTypeArguments); 43 } 44 } 45 } 46 }
1 package Reflection; 2 3 import java.lang.annotation.*; 4 import java.lang.reflect.Field; 5 6 /** 7 * author liulei 8 * data 5.22 9 * since 1.8 10 * version 1.0 11 * Description 反射获取注解 12 */ 13 public class Test10 { 14 public static void main(String[] args) throws Exception { 15 Class aClass = Class.forName("Reflection.student2"); 16 Annotation[] annotations = aClass.getAnnotations(); 17 for (Annotation a:annotations){ 18 System.out.println(a);//属性是私有的,所以没有输出属性的注解 19 } 20 //获得注解的value的值 21 table t = (table) aClass.getAnnotation(table.class); 22 String value = t.value(); 23 System.out.println(value); 24 //获得类指定的注解 25 Field name = aClass.getDeclaredField("name"); 26 zidingyi annotation = name.getAnnotation(zidingyi.class); 27 System.out.println(annotation.columnName()); 28 System.out.println(annotation.type()); 29 System.out.println(annotation.length()); 30 } 31 } 32 @table("db_student") 33 class student2{ 34 @zidingyi(columnName = "db_id",type = "int",length = 10) 35 private int id; 36 @zidingyi(columnName = "db_id",type = "int",length = 10) 37 private int age; 38 @zidingyi(columnName = "db_id",type = "int",length = 10) 39 private String name; 40 41 public student2() { 42 } 43 44 public student2(int id, int age, String name) { 45 this.id = id; 46 this.age = age; 47 this.name = name; 48 } 49 50 public void setId(int id) { 51 this.id = id; 52 } 53 54 public void setAge(int age) { 55 this.age = age; 56 } 57 58 public void setName(String name) { 59 this.name = name; 60 } 61 62 public int getId() { 63 return id; 64 } 65 66 public int getAge() { 67 return age; 68 } 69 70 public String getName() { 71 return name; 72 } 73 74 @Override 75 public String toString() { 76 return "student2{" + 77 "id=" + id + 78 ", age=" + age + 79 ", name='" + name + '\'' + 80 '}'; 81 } 82 } 83 @Target(ElementType.FIELD) 84 @Retention(RetentionPolicy.RUNTIME) 85 @interface zidingyi{ 86 String columnName(); 87 String type(); 88 int length(); 89 } 90 @Target(ElementType.TYPE) 91 @Retention(RetentionPolicy.RUNTIME) 92 @interface table{ 93 String value(); 94 }
Class.getAnnotations() 获取所有的注解,包括自己声明的以及继承的
Class.getAnnotation(Class< A > annotationClass) 获取指定的注解,该注解可以是自己声明的,也可以是继承的
Class.getDeclaredAnnotations() 获取自己声明的注解
作者:你的雷哥
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。