您的位置:首页 > 其它

反射机制调用类的方法,或操作成员,以及反射中的数组对象

2013-11-05 20:01 525 查看
使用反射机制可以取得类的方法的对象代表,则是一个java.lang.reflect.Method的实例。



如有一个实体类:

public class Student {
	
	private String name;
	private int score;
	
	public Student() {
	}
	public Student(String name, int score) {
		super();
		this.name = name;
		this.score = score;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return name+":"+score;
	}
	

}




现在新建一个主函数,对其进行操作,主要操作如下:



1、动态加载Student类,并生成该类的一个待操作对象:

//动态加载Student类
			Class c = Class.forName("Student");



2、利用反射机制去除函数对象:

//利用反射机制取出要使用的函数
			Class[] param1 = {String.class};//指定参数类型
 			Method setNameMethod = c.getMethod("setName", param1);

注意:

在制定参数类型是=时:基本类型用其包装类的.TYPE,而参数类型为包装类时用.class



3、执行方法

//方法的执行
			Object[] arg1 = {"name"};
			setNameMethod.invoke(o, arg1);




在此期间需要捕获异常:

catch (ClassNotFoundException e) {
			System.out.println("加载类错误");
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			System.out.println("未找到该方法");
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			System.out.println("类初始化失败");
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			System.out.println("参数错误");
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			System.out.println("方法执行出错");
			e.printStackTrace();
		}


我们也可以突破函数的存取限制来调用受保护甚至是私有的方法:



1、将上面的实体类的某方法setName设置为私有的



2、当我们继续以上面的方式运行时就会出现以下错误:



未找到该方法
java.lang.NoSuchMethodException: Student.setName(java.lang.String)
	at java.lang.Class.getMethod(Class.java:1605)
	at T2.main(T2.java:18)



3、此时我们应该这样取到并操作我们要的方法:

//利用反射机制取出要使用的函数
			Class[] param1 = {String.class};//指定参数类型
			Method setNameMethod = c.getDeclaredMethod("setName", param1);
			setNameMethod.setAccessible(true); //否则会产生java.lang.IllegalAccessException的异常


尽管直接存取类的原成员是不推荐的,但仍可一类似上面的方法来进行相关操作:

public class Student {
	
	public String name;
	private int score;
	
	@Override
	public String toString() {
		return name+":"+score;
	}
	

}




import java.lang.reflect.Field;

public class T2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		try {
			Class c = Class.forName("Student");   //动态加载
			Object o = c.newInstance();		//生成实例
			
			Field nameField = c.getField("name");	//获取public成员
			nameField.set(o, "name");
			
			Field scoreField = c.getDeclaredField("score"); //获取权限限制成员
			scoreField.setAccessible(true);	//设置能访问
			scoreField.setInt(o, 90);
			
			System.out.println(o);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
		
		
	}

}




对于反射机制中的数组对象,我们需要利用到 java.lang.reflect.Array
,简单的示例如下:



import java.lang.reflect.Array;

public class T4 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Class c= String.class;
		Object oArr = Array.newInstance(c, 5);
 		
		for (int i = 0; i < 5; i++) {
			Array.set(oArr, i, i+" ");
		}
		
		for (int i = 0; i < 5; i++) {
			System.out.print(Array.get(oArr, i));
 		}
		
		System.out.println();
		
		String[] strs = (String[]) oArr;
		for (String string : strs) {
			System.out.print(string+" ");
		}

	}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐