ITEEDU

入门准备

接触对象

对象导向

资源管理

对象容器(Container)

输入输出(I/O)

执行绪(Thread)

反射(Reflection)

metadata

数据库(JDBC)

舍遗补缺

Java Gossip: 呼叫方法

如果您会动态加载类别并使用有参数的建构函式(参考 生成物件),则动态呼叫所生成对象之方法并不是难事,直接以实例说明,首先写一个 Student类别:

Student.java
package onlyfun.caterpillar;
public class Student?{
	private String name;
	private int score;
	public Student() {
		name = "N/A";
	}
	public Student(String name, int score) {
		this.name = name;
		this.score = score;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setScore(int score) {
		this.score = score;
	}
	public String getName() {
		return name;
	}
	public int getScore() {
		return score;
	}
	public void showData() {
		System.out.println("name: " + name);
		System.out.println("score: " + score);
	}
}

再来写个动态加载与呼叫方法的程序:

InvokeMethod.java
package onlyfun.caterpillar;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class InvokeMethodDemo {
	public static void main(String[] args) {
		try {
			Class c = Class.forName(args[0]);
			Object targetObj = c.newInstance();
			Class[] param1 = {String.class};
			Method setName = c.getMethod("setName", param1);
			Object[] paramObjs1 = {"caterpillar"};
			setName.invoke(targetObj, paramObjs1);

			Class[] param2 = {Integer.TYPE};
			Method setScore =
			c.getMethod("setScore", param2);
			Object[] paramObjs2 = {new Integer(90)};
			setScore.invoke(targetObj, paramObjs2);
			Method showData =
			c.getMethod("showData", new Class[0]);
			showData.invoke(targetObj, new Object[0]);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
	}
}

执行结果:

java InvokeMethodDemo onlyfun.caterpillar.Student
name: caterpillar
score: 90

在很少的情况下,您会需要突破Java的存取限制来呼叫受护的或私有的方法(例如您拿到一个组件,但您没法修改它的原始码,而您又一定要呼叫某个私有方法),这时候您可以使用反射机制来达到您的目的,一个存取私有方法的例子如下:

Method privateTest = c.getDeclaredMethod("privateTest", new Class[0]);
privateTest.setAccessible(true);
privateTest.invoke(targetObj, new Object[0]);

所以在Java中即使宣告为私有方法或成员,仍可以透过反射机制存取私有方法,要突破权限仍是可以的,但该如何用则取决于您自己。