博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 反射
阅读量:7216 次
发布时间:2019-06-29

本文共 4199 字,大约阅读时间需要 13 分钟。

hot3.png

反射

简单的介绍反射的使用。

为什么要使用反射

  • 获取私有的属性方法,属性

  • 当不确定类的类型的使用

反射的使用

新建一个java项目,创建一个Person类,有name,sex,age三个属性,同时,有一个私有的构造函数和两个个共有构造函数。 添加set和get方法,toString方法。

具体代码如下:

package com.shxzhlxrr.reflect.vo;public class Person {	private String name;	private String sex;	private int age;		public Person(){			}		@SuppressWarnings("unused")	private Person(String name){		this.name = name;	}		public Person(String name ,String sex,int age){		this.name = name;		this.sex = sex;		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public String getSex() {		return sex;	}	public void setSex(String sex) {		this.sex = sex;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	@Override	public String toString() {		return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";	}}

获取私有构造函数,创建对象

第一步,我们需要先加载Person类,使用Class.forName方法加载,或返回一个Class对象,我们用变量cla保存。

通过clagetDeclaredConstructor构造方法,我们可以获取类的声明的构造函数,不管是私有的,还是共有的,都可以获取到。 因为我们的私有构造方法需要传入一个字符串类型的name,所以我们需要传入一个String.class,不传的话,会去获取无参构造函数。 我们会获取到一个java.lang.reflect.Constructor对象,用变量cons进行保存。

通过conssetAccessible传入true我们可以对私有的构造方法进行访问。

最后我们可以通过newInstance方法获取到一个Person的实例化对象,设置名字为张三。为了验证我们的名字是否设置成功,我们 可以打印实例化对象,如下所示,我们看到,我们的名字已经正确的设置了。

Person [name=张三, sex=null, age=0]

完整的测试代码如下所示:

public void testPrivateConstructor(){		try {			//加载类			Class cla = Class.forName("com.shxzhlxrr.reflect.vo.Person");			Constructor cons = cla.getDeclaredConstructor(String.class);			cons.setAccessible(true);			Object obj = cons.newInstance("张三");			System.out.println(obj);		} catch (Exception e) {			e.printStackTrace();		}	}

同理,获取私有的方法和属性是一样的,下面只罗列代码。

获取私有的方法,并调用

添加一个私有的方法say打印出姓名。

私有构造方法say如下:

private void say(){		System.out.println("我的名字是:"+this.name);	}

测试方法如下:

public void testPrivateMethodSay(){		try {			//加载类			Class cla = Class.forName("com.shxzhlxrr.reflect.vo.Person");			Constructor cons = cla.getDeclaredConstructor(String.class);			cons.setAccessible(true);			Object obj = cons.newInstance("张三");		    //获取私有方法			Method sayMethod = cla.getDeclaredMethod("say", null);			//设置权限			sayMethod.setAccessible(true);			//调用			sayMethod.invoke(obj, null);		} catch (Exception e) {			e.printStackTrace();		}	}

获取私有的属性

public void testPrivateField(){		try {			//加载类			Class cla = Class.forName("com.shxzhlxrr.reflect.vo.Person");			Constructor cons = cla.getDeclaredConstructor(String.class);			cons.setAccessible(true);			Object obj = cons.newInstance("张三");			//获取name属性			Field nameField = cla.getDeclaredField("name");			//设置访问权限			nameField.setAccessible(true);			//获得属性的值			String name = (String) nameField.get(obj);			System.out.println("name:"+name);		} catch (Exception e) {			e.printStackTrace();		}	}

当不确定类型的时候使用反射的例子

复制say方法,重命名为say2并该为共有的方法,测试使用。新建老师和学生类,继承人类这个类,并覆盖say2。 我把学生和老师的类型存放到一个数组中,通过反射去调用了say2方法。在我做过的以前的项目中,需要计算多个指标的 时候,我们可以把对应的计算类配置到数据库中,规定一个公共的方法,就可以调用这个方法进行各项指标的计算。

完整的代码如下所示:

package com.shxzhlxrr.reflect.vo;	//学生类	public class Student extends Person{		@Override		public void say2() {			System.out.println("我的名字是:"+this.getName()+",我的职业是学生");		}	}
package com.shxzhlxrr.reflect.vo;	//老师类	public class Teacher extends Person{		@Override		public void say2() {			System.out.println("我的名字是:"+this.getName()+",我的职业是老师");		}	}
public class ReflectTest2 {		/**		 * 给定类的名字,调用指定的方法		 * @param args		 */		public static void main(String[] args) {			ReflectTest2 reflectTest2 = new ReflectTest2();			String[] classArray = new String[]{"com.shxzhlxrr.reflect.vo.Teacher","com.shxzhlxrr.reflect.vo.Student"};			for(String className : classArray){				try {					reflectTest2.reflectMethod("say2", className);				} catch (Exception e) {					e.printStackTrace();				} 			}		}				public void reflectMethod(String methodName,String className) 				throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{			Class cla = Class.forName(className);			java.lang.reflect.Method method = cla.getDeclaredMethod(methodName, null);//正确的做法,参数也应是传进来的,不应该默认是null			method.invoke(cla.newInstance(), null);		}		}

转载于:https://my.oschina.net/smileblog/blog/1563344

你可能感兴趣的文章
二次排序
查看>>
CSS:如何清除a标签之间的默认留白间距
查看>>
selenium随笔
查看>>
leetcode599
查看>>
String类中“==”和“equals()”的区别
查看>>
leetcode--883
查看>>
the application could not be verified
查看>>
[转]Centos配置国内yum源
查看>>
redis数据类型和应用场景
查看>>
Spring IOC
查看>>
Fragment的onCreateView和onActivityCreate之间的区别(转)
查看>>
AC日记——统计难题 hdu 1251
查看>>
在仿真器中运行时跳过Windows Azure Startup任务
查看>>
android 获取路径目录方法以及判断目录是否存在,创建目录
查看>>
数列问题[HAOI2004模拟]
查看>>
2012各大IT公司校招笔试题整理
查看>>
phpcms 后台分页
查看>>
《需求工程》阅读笔记之六
查看>>
架构阅读笔记5
查看>>
IIS5.1使用虚拟目录部署网站
查看>>