一句话概括就是使用反射可以赋予jvm动态编译的能力,否则类的元数据信息只能用静态编译的方式实现,例如热加载,Tomcat的classloader等等都没法支持。
实现Java反射机制的类都位于java.lang.reflect包中:
-
Class类:代表一个类
-
Field类:代表类的成员变量(类的属性)
-
Method类:代表类的方法
-
Constructor类:代表类的构造方法
-
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
@Test private void test008() throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, IllegalAccessException { //第一种方式获取Class对象 Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。 Class stuClass = stu1.getClass();//获取Class对象 log.debug(stuClass.getName()); //第二种方式获取Class对象 Class stuClass2 = Student.class; log.debug(String.valueOf(stuClass == stuClass2)); //判断第一种方式获取的Class对象和第二种方式获取的是否是同一个 //第三种方式获取Class对象 try { Class stuClass3 = Class.forName("com.kolaer.cms.CmsApplicationTests.Student"); //注意此字符串必须是真实路径,就是带包名的类路径,包名.类名 log.debug(String.valueOf(stuClass3 == stuClass2)); //判断三种方式是否获取的是同一个Class对象 } catch (ClassNotFoundException e) { e.printStackTrace(); } log.debug("*****************获取公有、无参的构造方法*************"); Constructor con = stuClass.getConstructor(null); //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型 //2>、返回的是描述这个无参构造函数的类对象。 log.debug("*************获取公有字段**并调用*****************"); Field f = stuClass.getField("name"); log.debug(String.valueOf(f)); log.debug("***************获取私有的show4()方法******************"); Method m = stuClass.getDeclaredMethod("getUsername", String.class); log.debug(String.valueOf(m)); m.setAccessible(true);//解除私有限定 Object result = m.invoke(stu1, "zhangsan");//需要两个参数,一个是要调用的对象(获取有反射),一个是实参 log.debug("返回值:" + result); }