Java的反射与应用实战

反射的基本概念和方法

反射机制是在【运行状态】中:

  • 对于任意一个类,都能够知道这个类的所有属性和方法 (类->属性+方法)
  • 对于任意一个对象,都能够调用它的任意方法和属性 (对象->方法+属性) 即使得类变得完全透明

反射提供的功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法
  • 生成动态代理

优点:

  • 能够运行时动态获取类的实例(对象),大大提高系统的灵活性和扩展性(可解耦)
  • 与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"

end
  • 作者:suoyue_zhan(联系作者)
  • 发表时间:2020-09-23 04:16:00
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论