3.6 java基础总结①反射
反射
反射是Java的灵魂
反射是Java动态性最佳体现
动态性是在运行时去改变或绑定编译时确定的效果
Java不是动态语言,只有一定的动态性
Java利用反射实现动态性:运行时探究和使用编译时未知的类
类的加载机制
Class类(类模板)
加载 → 验证 → 准备 → 解析 → 初始化(静态属性初始化)
验证准备解析是连接阶段
反射通过名称来得到对象(类,属性,方法)
一句话:运行时探究和使用编译时未知的类
步骤
一、获得想要操作的 java.lang.Class对象
二、调用 getDeclaredMethods方法(属性方法行为)
三、使用reflection API来操作这些信息
属性:get/set ①②
构造:产生实例对象①②
方法:调用 ①②
属性①
getDeclareFields()全部
getFields 公共
②
getDeclareFields() 一个
getFields 一个
其他同理
1 package com.lovo.bean; 2 3 import java.io.Serializable; 4 5 /** 6 * Date: 2016-3-4-上午10:26:23 7 * Class_name: Student.java 8 * Package_name: com.lovo.bean 9 * Author: ZhangYue 10 * Description: 11 */ 12 public class Student extends Object implements Serializable,Runnable{ 13 14 private String name; 15 16 protected int age; 17 18 boolean gender; 19 20 public float height; 21 22 public Student(){ 23 24 } 25 26 public Student(String name){ 27 this.name = name; 28 } 29 30 private Student(String name,int age){ 31 this.name = name; 32 this.age = age; 33 } 34 35 public void study(int num){ 36 for(int i = 0; i < num; i++){ 37 System.out.println("Good Good Study,Day Day Up!"); 38 } 39 } 40 41 private void answer(){ 42 System.out.println("Open Yellow Gun!"); 43 } 44 45 @Override 46 public void run() { 47 // TODO Auto-generated method stub 48 System.out.println("奔跑吧,线程!"); 49 } 50 51 52 }
1 package com.lovo.test; 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 import java.lang.reflect.Modifier; 8 import com.lovo.bean.Student; 9 10 /** 11 * Date: 2016-3-4-上午10:29:36 12 * Class_name: TestMain.java 13 * Package_name: com.lovo.test 14 * Author: ZhangYue 15 * Description: 16 */ 17 public class ReflectMain { 18 19 /** 20 * @param args 21 */ 22 public static void main(String[] args) { 23 // TODO Auto-generated method stub 24 //反射的使用:在运行时探究和使用编译时未知的类 25 /* 26 * 1、获取类的Class对象(其实所有的类型都有Class对象) 27 */ 28 //1-1、根据一个实例对象(排除了基本数据类型),产生Class对象---动态性最低 29 Student stu = new Student(); 30 Class stuClass = stu.getClass();//来自于Object的方法 31 int[] array = new int[5]; 32 Class arrayClass = array.getClass(); 33 34 //1-2、根据类型名,获取Class对象---动态性低 35 Class stuClass1 = Student.class; 36 Class arrayClass1 = int[].class; 37 Class intClass = int.class;//基本数据类型.class的方式是JDK1.5以后提供的 38 Class voidClass = void.class; 39 Class intClass1 = Integer.TYPE;//JDK1.5以前,使用基本数据类型对应的包装类.TYPE 40 41 //1-3、根据类的字符串全类名,获取Class对象---动态性最高 42 Class stuClass2 = null; 43 try { 44 stuClass2 = Class.forName("com.lovo.bean.Student");//字符串全类名完全可以从程序外部输入 45 } catch (ClassNotFoundException e) { 46 // TODO Auto-generated catch block 47 e.printStackTrace(); 48 } 49 50 51 /* 52 * 2、探究Class对象中类的信息 53 */ 54 //2-1、探究类的声明部分 55 System.out.println("package " + stuClass.getPackage().getName() + ";");//得到包名 56 String allName = stuClass.getName();//得到类全名 57 String simpleName = stuClass.getSimpleName();//得到类的简单名 58 int classMod = stuClass.getModifiers();//得到类的修饰符 59 String classModStr = Modifier.toString(classMod);//得到修饰符的字符串形式 60 String superClassName = stuClass.getSuperclass().getName();//得到父类的Class对象 61 Class[] allInter = stuClass.getInterfaces();//得到所有接口的Class对象 62 String allInterNames = ""; 63 for(int i = 0; i < allInter.length; i++){ 64 allInterNames += allInter[i].getName(); 65 if(i != allInter.length - 1){ 66 allInterNames += ","; 67 } 68 } 69 70 System.out.println(classModStr + " class " + simpleName + 71 " extends " + superClassName + " implements " + allInterNames + "{"); 72 73 System.out.println("//属性"); 74 //2-2、属性的探究 75 Field[] allFields = stuClass.getDeclaredFields();//获取所有的属性 76 Field[] allPubicFields = stuClass.getFields();//获取所有的公共属性 77 //探究指定的属性 78 try { 79 Field field = stuClass.getDeclaredField("name");//根据属性名,返回指定的属性 80 Field publicField = stuClass.getField("height");//根据属性名,返回指定的公共属性 81 } catch (NoSuchFieldException e) { 82 // TODO Auto-generated catch block 83 e.printStackTrace(); 84 } catch (SecurityException e) { 85 // TODO Auto-generated catch block 86 e.printStackTrace(); 87 } 88 89 for(Field f : allFields){ 90 String fieldMod = Modifier.toString(f.getModifiers());//得到属性的修饰符 91 String fieldTypeStr = f.getType().getName();//得到属性的类型名 92 String fieldName = f.getName();//得到属性的名字 93 94 System.out.println("\t" + fieldMod + " " + fieldTypeStr + " " + fieldName + ";"); 95 } 96 97 System.out.println(); 98 System.out.println("//构造"); 99 100 //2-3、探究构造方法 101 Constructor[] allCons = stuClass.getDeclaredConstructors();//得到所有声明的构造 102 Constructor[] allPublicCons = stuClass.getConstructors();//得到所有公共的构造 103 try { 104 Constructor con = stuClass.getDeclaredConstructor(String.class,int.class);//得到指定的构造 105 Constructor publicCon = stuClass.getConstructor();//得到指定的公共构造 106 } catch (NoSuchMethodException e) { 107 // TODO Auto-generated catch block 108 e.printStackTrace(); 109 } catch (SecurityException e) { 110 // TODO Auto-generated catch block 111 e.printStackTrace(); 112 } 113 114 for(Constructor c : allCons){ 115 String conModStr = Modifier.toString(c.getModifiers());//得到构造的修饰符 116 String conName = c.getName();//得到构造方法的名字 117 Class[] parametersClassArray = c.getParameterTypes(); //得到所有的参数 118 String paramStr = ""; 119 for(Class paramClass : parametersClassArray){ 120 paramStr += paramClass.getSimpleName() + ","; 121 } 122 if(parametersClassArray.length != 0){ 123 paramStr = paramStr.substring(0,paramStr.length()-1); 124 } 125 System.out.println("\t" + conModStr + " " + conName + "(" + paramStr + ")"); 126 } 127 128 System.out.println(); 129 System.out.println("//方法"); 130 131 //2-4、探究方法 132 Method[] allMethods = stuClass.getDeclaredMethods();//得到所有声明的方法 133 Method[] allPublicMethods = stuClass.getMethods();//得到所有的公共方法 134 135 try { 136 Method method = stuClass.getDeclaredMethod("answer");//得到指定的声明方法 137 Method publicMethod = stuClass.getMethod("study",int.class);//得到指定的公共方法 138 } catch (NoSuchMethodException e) { 139 // TODO Auto-generated catch block 140 e.printStackTrace(); 141 } catch (SecurityException e) { 142 // TODO Auto-generated catch block 143 e.printStackTrace(); 144 } 145 146 for(Method m : allMethods){ 147 String methodMod = Modifier.toString(m.getModifiers()); 148 String returnStr = m.getReturnType().getName(); 149 String methodName = m.getName(); 150 String paramStr = ""; 151 Class[] params = m.getParameterTypes(); 152 for(int i = 0; i < params.length; i++){ 153 paramStr += params[i].getName(); 154 if(i != params.length - 1){ 155 paramStr += ","; 156 } 157 } 158 159 System.out.println("\t" + methodMod + " " + returnStr + " " 160 + methodName + "(" + paramStr + ")"); 161 } 162 System.out.println("}"); 163 164 165 /* 166 * 3、使用反射获取的信息 167 */ 168 //3-1、根据反射产生对象 169 //3-1-1、通过Class对象获取Constructor对象,然后产生实例对象(好处:可以调用任意符合访问修饰符的构造方法;坏处:代码太多) 170 // Constructor con = null; 171 // try { 172 // con = stuClass.getConstructor(String.class); 173 // } catch (NoSuchMethodException e) { 174 // // TODO Auto-generated catch block 175 // e.printStackTrace(); 176 // } catch (SecurityException e) { 177 // // TODO Auto-generated catch block 178 // e.printStackTrace(); 179 // } 180 // 181 // try { 182 // Student stu1 = (Student)con.newInstance("zhang3");//使用Constructor的newInstance方法产生对象 183 // Student stu2 = (Student)con.newInstance("zhang3"); 184 // System.out.println(stu1); 185 // System.out.println(stu2); 186 // } catch (InstantiationException e) { 187 // // TODO Auto-generated catch block 188 // e.printStackTrace(); 189 // } catch (IllegalAccessException e) { 190 // // TODO Auto-generated catch block 191 // e.printStackTrace(); 192 // } catch (IllegalArgumentException e) { 193 // // TODO Auto-generated catch block 194 // e.printStackTrace(); 195 // } catch (InvocationTargetException e) { 196 // // TODO Auto-generated catch block 197 // e.printStackTrace(); 198 // } 199 //3-1-2、直接通过Class对象产生实例对象(好处:代码少;坏处:只能调用到公共无参构造) 200 // try { 201 // Student stu1 = (Student)stuClass.newInstance(); 202 // System.out.println(stu1); 203 // } catch (InstantiationException e) { 204 // // TODO Auto-generated catch block 205 // e.printStackTrace(); 206 // } catch (IllegalAccessException e) { 207 // // TODO Auto-generated catch block 208 // e.printStackTrace(); 209 // } 210 211 //3-2、根据反射调用方法 212 // try { 213 // Method m = stuClass.getMethod("study",int.class); 214 // m.invoke(null,4);//使用Method对象提供的invoke方法,调用Method所代表的方法 215 // } catch (NoSuchMethodException e) { 216 // // TODO Auto-generated catch block 217 // e.printStackTrace(); 218 // } catch (SecurityException e) { 219 // // TODO Auto-generated catch block 220 // e.printStackTrace(); 221 // } catch (IllegalAccessException e) { 222 // // TODO Auto-generated catch block 223 // e.printStackTrace(); 224 // } catch (IllegalArgumentException e) { 225 // // TODO Auto-generated catch block 226 // e.printStackTrace(); 227 // } catch (InvocationTargetException e) { 228 // // TODO Auto-generated catch block 229 // e.printStackTrace(); 230 // } 231 232 //3-3、根据反射操作属性 233 try { 234 Field f = stuClass.getField("height"); 235 f.set(stu,1.8f);//用set方法赋值 236 System.out.println(f.get(stu));//用get方法取值 237 238 } catch (NoSuchFieldException e) { 239 // TODO Auto-generated catch block 240 e.printStackTrace(); 241 } catch (SecurityException e) { 242 // TODO Auto-generated catch block 243 e.printStackTrace(); 244 } catch (IllegalArgumentException e) { 245 // TODO Auto-generated catch block 246 e.printStackTrace(); 247 } catch (IllegalAccessException e) { 248 // TODO Auto-generated catch block 249 e.printStackTrace(); 250 } 251 252 } 253 254 }