黑马程序员技术交流社区
标题:
求助反射框架配置文件的问题
[打印本页]
作者:
陈红建
时间:
2012-7-31 10:52
标题:
求助反射框架配置文件的问题
本帖最后由 陈红建 于 2012-7-31 16:11 编辑
import java.io.*;
import java.util.*;
//利用反射来在指定的配置文件中读取类的名字
public class Test8 {
public static void main(String[] args) throws Exception {
InputStream ips= new FileInputStream("configclass.ini");
Properties props =new Properties();
props.load(ips);
ips.close();
String className=props.getProperty("className");
System.out.println(className);
Class.forName(className).newInstance();
//我在这里获取到类的名字之后怎么才能调用这个类,配置文件开面可以写自己的类吗?
//配置文件中类的名字 必须是 java.lang.*吗?
//我的配置文件是这么写的 className=Student 这个是我自己编写的一个测试类
//请问我应该怎么调用它?我自上面newInstance之后 调用总是报错
}
}
作者:
杨志
时间:
2012-7-31 12:46
这里用到的是反射的机制!
这里你想要调用这个类有两种方式!
可以选择直接newInstace 实例化对象。如下:
Class<?> clazz = Class.forName(className); //首先加载驱动
Object obj = clazz.newInstance(); //实例化对象
Method method = clazz.getMethod(methodName); //根据方法名,获取Method对象,
result = (String)method.invoke(obj); //调用方法
复制代码
也可以先获取构造方法,利用构造方法去实例化对象。如下:
Constructor<?> ct = Class.forName("com.test.Person").getConstructor
Person person = (Person)ct.newInstance();
复制代码
这里要注意的是开始只是获取构造器,但并没有去初始化它。只有在实例对象的时候,才会去调用构造器。
还有就是其实第一种方式也需要去调用构造方法。
如果不信的话可以去查下API 或者JDK 的源码。下面给一段JDK核心代码:
private T newInstance0()
throws InstantiationException, IllegalAccessException
{
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public Object run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw new InstantiationException(getName());
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class caller = Reflection.getCallerClass(3);
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
复制代码
这些也不用全部看懂!仔细看看就知道,它同样也要去获取构造器去实例化对象。
作者:
涂金哲
时间:
2012-7-31 13:45
Class.forName(className).newInstance();完成到这句代码已经获得了实例 接着我们可以通过实例对象的字节码获取指定名称的方法(这里可以指定方法的名称,就是配置文件类中所指定的类包含的方法) 然后通过获得的这个获取的方法调用invoke方法 就可以运行了,张老师的高新技术中有的可以看看 ……还有配置文件里指定的类名称一定要完整 比如:className=包名.类名
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2