当类加载器将类加载进jvm之后,jvm会创建每一个类的元数据对象(Class),这个元数据对象(Class)记录着这类的所有信息,java语言允许通过元数据对象动态的创建对象实例,这种机制就称为java的反射机制,基本上所有框架的底层都用到了反射机制,spring、mybatis、servlet都用到了
1.如何获取一个类的元数据对象(Class)呢
现在有一个User类
package com.niu.demo;public class User {private String name;private String password;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
获取User的元数据对象(Class)方式
public class Main2 {public static void main(String[] args) {Class<User> aClass1 = User.class; // 1、类名.classClass<?> aClass2 = Class.forName("com.niu.demo.User"); //2、类完整的路径名User user = new User();Class<? extends User> aClass = user.getClass(); //3、对象引用.getClass()方式}
}
2.如何通过类的元数据对象(Class)创建对象呢
我们采用第一种获取Class对象的方式
Class<User> aClass1 = User.class; // 1、类名.class
User user = aClass1.newInstance();
这样就完成了通过反射的方式完成了类的创建
3.还可以对通过Class对象做什么
我们可以通过元数据Class对象获取对象的所有信息,如方法、属性、父类、接口、构造器。。。。
3.1 给属性赋值
public class Main2 {public static void main(String[] args) throws Exception {//1、第一种方式User user = new User();user.setName("张三");System.out.println(user.getName());//通过反射给属性赋值 传入属性名Field field = user.getClass().getDeclaredField("name");field.setAccessible(true);field.set(user,"李四");System.out.println(user.getName());//2、第二种方式User user1 = User.class.newInstance();user1.setName("王五");System.out.println(user1.getName());}
}
输出
3.2 反射调用对象方法
我们在User加入如下方法
public boolean passwordCheck(String password){if (password==null || password.length()<3){System.out.println("password can't be used");return false;}else {System.out.println("password is ok");return true;}}
调用测试
public static void main(String[] args) throws Exception {User user = new User();//传入方法名和参数类型Method passwordCheck = user.getClass().getDeclaredMethod("passwordCheck",String.class);Object invoke1 = passwordCheck.invoke(user, "12");System.out.println(invoke1);Object invoke2 = passwordCheck.invoke(user, "123");System.out.println(invoke2);}
输出
4、框架里是如何使用反射的
tomcat里web.xml
<servlet><servlet-name>HelloServlet</servlet-name><servlet-class>servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/servlet/HelloServlet</url-pattern></servlet-mapping>
其中:<servlet-class>配置的完整类路径,然后通过Class.forName()来实例化servlet
spring的ioc mybatis的mapper等等等等。。。 都是用到了反射