当类加载器将类加载进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、类名.class
Class<?> 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;
}
}
调用测试
扫描二维码关注公众号,回复:
15666836 查看本文章
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等等等等。。。 都是用到了反射