Java总结坚持一百天1--java反射简单总结

1、反射是什么?
2、反射对象
3、反射方法
4、反射在平时的应用

-----------------------------------------------反射是什么?----------------------------------------------------
1、反射是什么?
Java反射机制是一个非常强大的功能,在很多大型项目比如Spring, Mybatis中都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。本文我们就从实际应用的角度出发,来应用一下Java的反射机制。

通俗的讲:知道类全名和构造方法,我们可以通过反射得到一个对象。获得一个对象并知道他的方法,我们可以通过方法名执行该方法。适用于批量的重复工作的简化工作。

-----------------------------------------------反射对象----------------------------------------------------
2、反射对象

github源码地址
一个对象的初始化,就是对构造函数的初始化,那么构造函数有的没有参数,有的没有参数。那我们怎么用反射进行初始化呢?下面我们先看一个对没有参数的构造方法进行初始化的形式,代码如下:
准备工作,首先我们做一个Bean 来作为初始化的对象:

package com.tt.reflect;

public class TestBean {
	
	private String status = "锁定";
	
	private String name;
	
	private String age;
	
	
	public TestBean() {
	}
	
	public TestBean(String status) {
		this.status = status;
	}
	
	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "TestBean [name=" + name + ", age=" + age + "]";
	}
	
	

}

bean做好之后我们接下来对bean进行一下初始化,(无参初始化)

public TestBean getBean() {
		TestBean testBean =null;
		try {
			testBean = (TestBean) Class.forName("com.tt.reflect.TestBean").newInstance();
		} catch (InstantiationException e) {
			//该对象不能实例化
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			//调用该类的构造方法,是Private访问权限。
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			//没有找到对应的类
			e.printStackTrace();
		}
		return testBean;
	}

可以做一个简单的测试,看看这段代码是否可以进行TestBean的一个初始化。
那么接下来我们再写一个使用有参数的构造方法,来传参进行对象初始化,代码如下:

	public TestBean getParamBean() {
		TestBean testBean = null;
		
		try {
			testBean = (TestBean) Class.forName("com.tt.reflect.TestBean").getConstructor(String.class).newInstance("不锁定");
		} catch (InstantiationException e) {
			//该对象不能实例化
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			//调用该类的构造方法,是Private访问权限。
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			//数据异常的错误
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			//反射异常
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			//此方法不存在异常
			e.printStackTrace();
		} catch (SecurityException e) {
			//权限不足
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			//没有找到类
			e.printStackTrace();
		}
		return testBean;
	}

如上可以看到,我们分别对无参构造方法和有参构造方法进行了初始化。
那么我怎么怎么来验证他们之间的区别呢?
我们写一个测试的MainTest类来测试一下:

package com.tt.reflect;
public class MainTest {
	public static void main(String[] args) {
		ReflectTest r = new ReflectTest();
		//注意点,如果bean里面有其他的构造函数,则需要自己写明 无参构造函数否在会报错
		TestBean bean = r.getBean();
		System.out.println("bean:"+bean.getStatus());
		TestBean paramBean = r.getParamBean();
		System.out.println("paramBean:"+paramBean.getStatus());
	}
}

通过以上两种方式初始化测试结果如下:

bean:锁定
paramBean:不锁定

第一个没有参数,没有改变status属性,第二个传入参数为不锁定,实现了传参初始化。

-----------------------------------------------反射方法----------------------------------------------------
3、反射方法

/**
	 * 反射方法
	 * @return
	 */
	public Object reflectMethod() {
		Object obj = null;
		//获取一个bean
		TestBean bean = getBean();
		try {
			//有参方法  一个方法可以有多个参数 根据参数的循序指定  参数的类型即可  逗号分隔
			Method method = bean.getClass().getMethod("setName", String.class);
			//指定set方法
			method.invoke(bean, "sad");
			//无参方法
			Method method2 = bean.getClass().getMethod("getName");
			obj = method2.invoke(bean);
			
		} catch (NoSuchMethodException e) {
			// 没有该方法
			e.printStackTrace();
		} catch (SecurityException e) {
			// 权限
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// 不循序访问  属性或者方法为私有
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// 参数传出异常
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// 发射异常
			e.printStackTrace();
		}
		
		return obj;
		
	}

测试类:

扫描二维码关注公众号,回复: 5118051 查看本文章
package com.tt.reflect;

public class MainTest {
	
	public static void main(String[] args) {
		ReflectTest r = new ReflectTest();
		//注意点,如果bean里面有其他的构造函数,则需要自己写明 无惨构造函数否在会报错
		TestBean bean = r.getBean();
		System.out.println("bean:"+bean.getStatus());
		
		TestBean paramBean = r.getParamBean();
		System.out.println("paramBean:"+paramBean.getStatus());
		
		Object reflectMethod = r.reflectMethod();
		System.out.println(reflectMethod);
	}

}

测试结果:

bean:锁定
paramBean:不锁定
sad

扩展思考,
1、如何简化数据库操作?
2、spring和mybatis 中有没有用到反射的例子?
3、反射有什么好处?优点在什么地方?
4、我该怎么使用反射增强写代码的效率?怎么使用反射来自己写一些常用的工具包?

-----------------------------------------------反射在平时的应用----------------------------------------------------
4、反射在平时的应用
spring IoC其实是一个很好的例子,通过配置文件 类全名 把bean放在容器里面,可以根据类全名 和参数 把bean放在容器里面。通过xml初始化bean 放在容器的过程使用了反射,感兴趣可以看一下源码。

参照地址

猜你喜欢

转载自blog.csdn.net/ppwwp/article/details/86556276