(初学者自学总结)
学习理由:
框架底层重要的实现原理之一(反射)
反射就是在"java运行系统"时期 到"类加载器验证字节码的正确性"
即运行期间动态的操作类加载器的字节码文件从而获得整个类文件。
1.获取一个类的class对象的方式
eg:获取Person实体类
①:通过.class获取:System.out.println(Person.class);
②:通过class对象中forName()获取:Class<?> aClass = Class.forName("deep.entity.Person");
③:通过类的实例获取:Person person = new Person(); System.out.println(person.getClass());
2、主要方法使用练习
我们有一个BookEntity实体类,通过反射来加载这个类
我封装了四个方法,分别打印类信息、属性信息、方法信息、构造器信息
①:获取类的信息:
1 private static void getClassInfo(){ 2 3 //获取class对象 4 5 Class<BookEntity> clazz = BookEntity.class; 6 7 System.out.println("类的全名称:" + clazz.getName()); 8 9 System.out.println("类的简单类名:" + clazz.getSimpleName()); 10 11 System.out.println("类的修饰符:" + Modifier.toString(clazz.getModifiers())); 12 13 }
②:获取类中所有属性的信息:
private static void getClassFieldInfo() { Class<BookEntity> clazz = BookEntity.class; Object instance = clazz.newIntance(); Field bookNameField = clazz.getDeclareField("bookName"); //bookName字段是私有的需要设置字段访问权限 bookNameField.setAccessible(true); //调用字段对应set方法 bookNameField.set(instance,"java"); //获取刚刚设置到字段中的值 Object value = bookNameField.get(instance); System.out.println(value); }
附上:set方法的源码/get方法的源码
1 @CallerSensitive 2 public void set(Object obj, Object value) 3 throws IllegalArgumentException, IllegalAccessException 4 { 5 if (!override) { 6 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 7 Class<?> caller = Reflection.getCallerClass(); 8 checkAccess(caller, clazz, obj, modifiers); 9 } 10 } 11 getFieldAccessor(obj).set(obj, value); 12 }
1 @CallerSensitive 2 public Object get(Object obj) 3 throws IllegalArgumentException, IllegalAccessException 4 { 5 if (!override) { 6 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 7 Class<?> caller = Reflection.getCallerClass(); 8 checkAccess(caller, clazz, obj, modifiers); 9 } 10 } 11 return getFieldAccessor(obj).get(obj); 12 } 13 14
③:获取方法的所有信息:
1 /** 2 * 获取方法的所有信息 3 * @throws SecurityException 4 * @throws NoSuchMethodException 5 * @throws IllegalAccessException 6 * @throws InstantiationException 7 * @throws InvocationTargetException 8 * @throws IllegalArgumentException 9 */ 10 private static void getClassForMethodInfo() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 11 // TODO Auto-generated method stub 12 13 //获取Class对象 14 Class<BookEntity> clazz = BookEntity.class; 15 16 //获取所有public修饰的方法 17 Method[] methods = clazz.getMethods(); 18 for(Method method : methods){ 19 System.out.println(method); 20 System.out.println("访问修饰符:" + Modifier.toString(method.getModifiers())); 21 System.out.println("返回类型名称:" + method.getReturnType().getSimpleName()); 22 System.out.println("方法名称:" + method.getName()); 23 System.out.println("参数类型:" + Arrays.toString(method.getParameterTypes())); 24 System.out.println("参数个数:" + method.getParameterCount() ); 25 System.out.println("----------------------------------------------"); 26 } 27 28 //通过反射实例化一个对象 29 BookEntity instance = clazz.newInstance(); 30 31 //获取单个方法 32 Method set = clazz.getDeclaredMethod("setBookPrice",Double.class); 33 //开启方法访问权限(如果访问修饰符非public) 34 set.invoke(instance,45.7); 35 36 //再获取get方法来获取刚刚设置的值 37 Method get = clazz.getDeclaredMethod("getBookPrice"); 38 39 System.out.println(get.invoke(instance)); 40 41 42 //获取当前类中所有定义的方法 43 methods = clazz.getDeclaredMethods(); 44 for(Method method : methods){ 45 System.out.println(method); 46 } 47 }
④获取构造器信息:
1 /** 2 * 获取构造器信息 3 * @throws SecurityException 4 * @throws NoSuchMethodException 5 * @throws InvocationTargetException 6 * @throws IllegalArgumentException 7 * @throws IllegalAccessException 8 * @throws InstantiationException 9 */ 10 private static void getClassForConstructor() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 11 // TODO Auto-generated method stub 12 //获取class对象 13 Class<BookEntity> clazz = BookEntity.class; 14 //获取所有public修饰的函数 15 Constructor<?>[] constructors = clazz.getConstructors(); 16 17 for(Constructor constructor : constructors){ 18 System.out.println(constructor); 19 } 20 21 System.out.println("------------------------------------------"); 22 23 //湖区类中所有定义的构造函数 24 constructors = clazz.getDeclaredConstructors(); 25 for(Constructor constructor : constructors){ 26 System.out.println(constructor); 27 System.out.println("访问修饰符:" + Modifier.toString(constructor.getModifiers())); 28 System.out.println("构造器名称:" + constructor.getName()); 29 System.out.println("参数列表:" + Arrays.toString(constructor.getParameterTypes())); 30 System.out.println("----------------------------------------"); 31 } 32 33 //调用指定构造函数 34 Constructor<BookEntity> constructor = clazz.getDeclaredConstructor(int.class,String.class); 35 constructor.setAccessible(true); 36 BookEntity instance = constructor.newInstance(100,"三国演义"); 37 System.out.println(instance); 38 System.out.println(instance.getBookName()); 39 System.out.println(instance.getBookAuthor()); 40 System.out.println(instance.getBookId()); 41 System.out.println(instance.getBookPrice()); 42 }
运行效果:
原文地址:https://www.cnblogs.com/deepSleeping/p/9381785.html
时间: 2024-10-09 12:01:56