java之反射

什么是反射

用比较官方的话来说,反射就是java语言中的一种机制,通过这种机制能够动态读写属性,调用方法,实例化对象,它能让我们更灵活的操作代码,对于框架设计来说,反射就是基础.

看到这里,懵逼了吧?哈哈哈哈,换句话说,就是对于任意一个类,都能通过反射获取到属性、方法和实例化对象。什么?还不懂,举个比较通俗的例子:

有个人叫小明,会唱歌跳舞,看成对象,那么,他的name属性就是小明,行为方法就是会唱歌,除了了解他的人,可能才知道他叫小明,他会唱歌,但是不认识他的人呢,他也知道,没错,他就是反射!!

反射的运用案例

有一个学生类,常规我们实例化对象,都是直接这样:

Student stu=new Student();

而反射是这样:

//反射获取类对象
		Class<?> clz = Class.forName("com.xiaoyang.Student");
		//反射实例化对象
		Student newInstance =(Student) clz.newInstance();

看到这,是不是困惑了?反射代码不是更多了吗?但是要知道,我们发布一个项目到服务器,服务器是并不知道我们要实例化什么类的,那么它是怎么获取到我们自己项目中的类对象的呢?看web.xml配置文件:

  <servlet>
  	<servlet-name>jrebelServlet</servlet-name>
  	<servlet-class>com.xml.JrebelServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>jrebelServlet</servlet-name>
  	<url-pattern>/jrebelServlet</url-pattern>
  </servlet-mapping>

项目在发布时,它会有一个请求路径,也就是

<url-pattern>/jrebelServlet</url-pattern>

服务器会通过这个请求路径,通过建模,获取到

<servlet-name>jrebelServlet</servlet-name>

再通过获取到的servlet-name值,在

  <servlet>
  	<servlet-name>jrebelServlet</servlet-name>
  	<servlet-class>com.xml.JrebelServlet</servlet-class>
  </servlet>

中获取到servlet-class,也就是我们项目中的处理操作的类。像tomcat服务器,它也是要获取请求路径,然后获取到项目里的类对象进行记成htppservlet类,然后再进行操作的

反射的常用方法

所有的反射,都是从获取类对象开始的,获取类对象,我们有三种方式:

  1. Class<?> clz = Class.forName("com.xiaoyang.Student");
  2. 类名.class Class clz=Student.class;
  3. 类对象.getClass();Student stu=new Student(); Class<? extends Student> clz = stu.getClass();

获取类对象后,我们就可以用反射进行操作了,首先是调用构造方法:

//无参构造方法
		Class<?> clz = Class.forName("com.xiaoyang.Student");
		Object stu = clz.newInstance();
//一个参数的构造方法
		Constructor<?> constructor = clz.getConstructor(String.class);
		Student newInstance =(Student) constructor.newInstance("s001");
//两个参数的构造方法
		Constructor<?> constructor2 = clz.getConstructor(String.class,String.class);
	    Student newInstance2 = (Student)constructor2.newInstance("s001","zs");` //调用私有构造方法
	    Constructor<?> declaredConstructor = clz.getDeclaredConstructor(Integer.class);
	    declaredConstructor.setAccessible(true);
	    Object newInstance3 = declaredConstructor.newInstance(22);`

用反射读写属性:

	//反射获取类对象
		Class<?> clz = Class.forName("com.xiaoyang.Student");
		//反射实例化对象
		Student newInstance =(Student) clz.newInstance();
		//给对象赋值
		newInstance.setSname("zs");
	//反射读取属性
		Field field = clz.getDeclaredField("sname");
		field.setAccessible(true);

反射读写属性这里,还有一个比较重要的方法就是获取类的所有属性值:

  //反射读取类所有属性值
		Field[] fields = clz.getDeclaredFields();
		for (Field field2 : fields) {
			field2.setAccessible(true);
			System.out.println(field2.get(newInstance));
		}

然后就是反射调用方法:

//反射获取类对象
	Class<?> clz = Class.forName("com.xiaoyang.Student");
	//反射实例化对象
	Object stu = clz.newInstance();
	//获取方法
	Method method = clz.getMethod("hello");

私有方法:

    Method method3 = clz.getDeclaredMethod("add",Integer.class ,Integer.class);
	method3.setAccessible(true);
	Object invoke3 = method3.invoke(stu,20,5);

需要注意的是,所有的私有属性、方法,都需要加上这个方法:

setAccessible(true)
尾言

反射对于框架来说,无疑是非常重要的,框架的设计者,并不会知道使用者的项目会建什么类,创建什么方法,使用反射,就可以实现了.所以理解好反射,可以更好的理解框架的原理和灵活操作代码…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值