黑马程序员技术交流社区

标题: 反射Or Eclispe的问题 [打印本页]

作者: 胡雷    时间: 2011-12-4 22:40
标题: 反射Or Eclispe的问题
本帖最后由 wir478 于 2011-12-5 12:49 编辑

碰到个应该是Eclipse的问题:


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestReflection {
       
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
                String str = "T";   
                Class.forName(str);     

                Class c = Class.forName(str);
                Object o = c.newInstance();     
               
                Method[] methods = c.getMethods();
                for(Method m : methods) {
                        System.out.println(m.getName());
                }
               

                for(Method m : methods) {
                        if(m.getName().equals("mm")) {
                                m.invoke(o);
                        }
                }
               
        }
}

class T {
       
        static {
                System.out.println("T loader!");
        }
       
        public T() {
                System.out.println("T constructed!");
        }
       
        int i;
        String s;
       
        public void m1(int i) {
                this.i = i;
        }
       
        public void mm() {
                System.out.println("mm invoked");
        }
       
        public String getS() {
                return s;
        }
}

我在Eclipse运行这段代码的时候,老是报错:Exception in thread "main" java.lang.ClassNotFoundException: T。但是将文件内容拷贝到其它地方,用命令行窗口编译和运行都没有问题。搞了半天没找到原因,求帮助。。。。
作者: 段波    时间: 2011-12-4 22:58
你把T的包名加上就可以了,类加载器加载路径问题

作者: 胡雷    时间: 2011-12-4 23:05
段波 发表于 2011-12-4 22:58
你把T的包名加上就可以了,类加载器加载路径问题

我在程序的开头写了package Reflect;   您说的是在哪加?
作者: 韩军博    时间: 2011-12-4 23:05
在Eclipse中你把两个类的位置换一下估计就正确了
作者: 段波    时间: 2011-12-4 23:07
String str = "T"; 改成String str="cn.hema.T" 你相应的包就可以了
作者: 颜秉武    时间: 2011-12-4 23:09
Class c = Class.forName(str);
Class.forName(str);里面需要的是全路径
这个方法的参数在javaseapi中的解释是:
参数:
className - 所需类的完全限定名。


这是api对这个方法的解释:
forName
public static Class<?> forName(String className)
                        throws ClassNotFoundException返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
  Class.forName(className, true, currentLoader)
其中 currentLoader 表示当前类的定义类加载器。
例如,以下代码片段返回命名为 java.lang.Thread 的类的运行时 Class 描述符。

   Class t = Class.forName("java.lang.Thread")
调用 forName("X") 将导致命名为 X 的类被初始化。


参数:
className - 所需类的完全限定名。
返回:
具有指定名的类的 Class 对象。
抛出:
LinkageError - 如果链接失败
ExceptionInInitializerError - 如果此方法所激发的初始化失败
ClassNotFoundException - 如果无法定位该类



希望可以对你有所帮助

作者: 颜秉武    时间: 2011-12-4 23:11
  1. package dsfdghd;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;

  4. public class TestReflection {
  5.         
  6.         public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  7.                 String str = "dsfdghd.T";   
  8.                 Class.forName(str);     

  9.                 Class c = Class.forName(str);
  10.                 Object o = c.newInstance();     
  11.                
  12.                 Method[] methods = c.getMethods();
  13.                 for(Method m : methods) {
  14.                         System.out.println(m.getName());
  15.                 }
  16.                

  17.                 for(Method m : methods) {
  18.                         if(m.getName().equals("mm")) {
  19.                                 m.invoke(o);
  20.                         }
  21.                 }
  22.                
  23.         }
  24. }

  25. class T {
  26.         
  27.         static {
  28.                 System.out.println("T loader!");
  29.         }
  30.         
  31.         public T() {
  32.                 System.out.println("T constructed!");
  33.         }
  34.         
  35.         int i;
  36.         String s;
  37.         
  38.         public void m1(int i) {
  39.                 this.i = i;
  40.         }
  41.         
  42.         public void mm() {
  43.                 System.out.println("mm invoked");
  44.         }
  45.         
  46.         public String getS() {
  47.                 return s;
  48.         }
  49. }
复制代码
这样就没错了
作者: 胡雷    时间: 2011-12-4 23:15
很感谢二位的回答,问题已经解决。但是视频中老师并没有写包名啊,也是可以的。为什么到哪我这就不行了呢?什么情况下可以不写也可以运行呢、?
作者: 颜秉武    时间: 2011-12-4 23:28
既然楼主说将文件内容拷贝到其它地方,用命令行窗口编译和运行都没有问题

那就应该是eclipse问题了:

eclipse是使用它本身的jre编译的,可能和环境变量所指路径有关吧!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2