A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈红建 中级黑马   /  2012-7-31 10:52  /  1721 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 陈红建 于 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之后 调用总是报错
        }
}

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 鼓励一下

查看全部评分

2 个回复

倒序浏览
这里用到的是反射的机制!
这里你想要调用这个类有两种方式!  
可以选择直接newInstace 实例化对象。如下:
  1. Class<?> clazz = Class.forName(className);                        //首先加载驱动
  2.         Object obj = clazz.newInstance();                              //实例化对象
  3.         Method method = clazz.getMethod(methodName);      //根据方法名,获取Method对象,
  4.         result = (String)method.invoke(obj);                           //调用方法


复制代码
也可以先获取构造方法,利用构造方法去实例化对象。如下:

  1. Constructor<?> ct = Class.forName("com.test.Person").getConstructor
  2. Person person = (Person)ct.newInstance();
复制代码
这里要注意的是开始只是获取构造器,但并没有去初始化它。只有在实例对象的时候,才会去调用构造器。
还有就是其实第一种方式也需要去调用构造方法。
如果不信的话可以去查下API 或者JDK 的源码。下面给一段JDK核心代码:
  1. private T newInstance0()
  2.         throws InstantiationException, IllegalAccessException
  3.     {
  4.         // NOTE: the following code may not be strictly correct under
  5.         // the current Java memory model.

  6.         // Constructor lookup
  7.         if (cachedConstructor == null) {
  8.             if (this == Class.class) {
  9.                 throw new IllegalAccessException(
  10.                     "Can not call newInstance() on the Class for java.lang.Class"
  11.                 );
  12.             }
  13.             try {
  14.                 Class[] empty = {};
  15.                 final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
  16.                 // Disable accessibility checks on the constructor
  17.                 // since we have to do the security check here anyway
  18.                 // (the stack depth is wrong for the Constructor's
  19.                 // security check to work)
  20.                 java.security.AccessController.doPrivileged
  21.                     (new java.security.PrivilegedAction() {
  22.                             public Object run() {
  23.                                 c.setAccessible(true);
  24.                                 return null;
  25.                             }
  26.                         });
  27.                 cachedConstructor = c;
  28.             } catch (NoSuchMethodException e) {
  29.                 throw new InstantiationException(getName());
  30.             }
  31.         }
  32.         Constructor<T> tmpConstructor = cachedConstructor;
  33.         // Security check (same as in java.lang.reflect.Constructor)
  34.         int modifiers = tmpConstructor.getModifiers();
  35.         if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
  36.             Class caller = Reflection.getCallerClass(3);
  37.             if (newInstanceCallerCache != caller) {
  38.                 Reflection.ensureMemberAccess(caller, this, null, modifiers);
  39.                 newInstanceCallerCache = caller;
  40.             }
  41.         }
  42.         // Run constructor
  43.         try {
  44.             return tmpConstructor.newInstance((Object[])null);
  45.         } catch (InvocationTargetException e) {
  46.             Unsafe.getUnsafe().throwException(e.getTargetException());
  47.             // Not reached
  48.             return null;
  49.         }
  50.     }
复制代码
这些也不用全部看懂!仔细看看就知道,它同样也要去获取构造器去实例化对象。

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
Class.forName(className).newInstance();完成到这句代码已经获得了实例  接着我们可以通过实例对象的字节码获取指定名称的方法(这里可以指定方法的名称,就是配置文件类中所指定的类包含的方法) 然后通过获得的这个获取的方法调用invoke方法 就可以运行了,张老师的高新技术中有的可以看看 ……还有配置文件里指定的类名称一定要完整 比如:className=包名.类名
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马