反射机制是在【运行状态】中:
对于任意一个类,都能够知道这个类的所有属性和方法 (类->属性+方法)
对于任意一个对象,都能够调用它的任意方法和属性 (对象->方法+属性)
即-使类完全透明
反射提供的功能:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
生成动态代理
优点:
- 能够运行时动态获取类的实例(对象),大大提高系统的灵活性和扩展性(可解耦)
- 与Java动态编译相结合,可以实现无比强大的功能
缺点:
- 使用反射的性能较低
- 使用反射相对来说不安全
- 破坏了类的封装性,可以通过反射获取这个类的私有方法和属性
获取反射对象(反射入口):
- Class.forName(全类名:包名+类名):需要处理异常(常用)
- 类名.class
- 对象.getClass()
//Class.forName("全类名") -->>需要处理异常-->>常用
Class<?> perClazz = null;
try {
perClazz = Class.forName("xxx");
System.out.println(perClazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
获取反射的相关操作:
// 获取所有的公共的方法(1.本类 以及 父类、接口中的所有方法 2.符合访问修饰符规律)
Method[] methods = perClazz.getMethods();
// 获取当前类的所有方法(1.只能是当前类 2.忽略访问修饰符限制)
Method[] declaredMethods = perClazz.getDeclaredMethods();
//获取所有的接口-接口-多实现
Class<?>[] interfaces = perClazz.getInterfaces();
//获取所有的父类-单继承
Class<?> superclass = perClazz.getSuperclass();
//获取所有的构造方法.getConstructors()
Constructor<?>[] constructors = perClazz.getConstructors();
//获取公共属性.getFields()
Field[] fields = perClazz.getFields();
// 所有属性 (属性的 :公共属性\所有属性的区别 同“方法”)
Field[] declaredFields = perClazz.getDeclaredFields();
//获取当前反射所代表类(接口)的对象(实例).newInstance()
Object instance = perClazz.newInstance();
//通常使用new操作符创建新的实例:
Person p = new Person();
//如果通过反射来创建新的实例,可以调用Class提供的newInstance()方法:
Person p = Person.class.newInstance();
//调用Class.newInstance()的局限是,它只能调用该类的public无参数构造方法。
//如果构造方法带有参数,或者不是public,就无法直接通过Class.newInstance()来调用。
//通过设置setAccessible(true)来访问非public构造方法
使用反射来操作统一的http请求类:
public class BaseServlet extends HttpServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
//乱码处理
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=UTF-8");
String action = request.getParameter("action");
if (action==null||"".equals(action)) {
response.getWriter().write("您提交是的非法数据!!");
return;
}
try {
//反射:可以做未来不确定的事情。 根据输入的action动作通过反射机制得到本对象的对应方法对象
Method method = this.getClass().getMethod(action, HttpServletRequest.class,HttpServletResponse.class);
//使用方法对象method调用本对象的方法
method.invoke(this, request,response);
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("您提交是的非法数据!!");
}
}
}
其他业务功能类(CURD)继承BaseServlet而非继承HttpServlet
jsp-action=“XXXServlet?action=CURD”