2012-02-24 70 views
0

说如果我有一个名为Car的类,我可以在某些情况下使用下面的代码行。Java运行时间级反射

Car.class

我的问题是有没有办法,如果用户在运行时提供了一个类名,我可以做出同样类型的呼叫。试过类似于下面的东西,但没有喜悦,有没有办法可以做到这一点。

String className = "Car"; 
Class.forName(className).class; 

此外,我需要能够动态地施放,如果用户指定对象的列表,我需要能够动态地投。

例如而不是Car myCar = (Car) object

我需要能够让用户在运行时指定类的名称/类型,以便我需要能够沿ClassName myObj = (ClassName) object的行做些事情。

+1

可不可以给一个场景,在那里你会用吗? Java反射速度很慢,通常你不需要这种投射。也许有更好的方法来做到这一点? – Tim 2012-02-24 09:42:28

回答

0

您希望与myObj进行交互,所以不要考虑这些体操操作,可以考虑添加一个接口来模拟您想要与对象进行的交互,然后在代码中使用该接口。然后可以验证用户提供的类来实现适当引发的必要接口和错误。

2

Class.forName("Car")已经返回相同的Car.class

对于铸造,您可以使用Class.forName("Car").cast(object),这将返回一个Car对象。看看API,主要是java.lang.Class的一部分。

而且,因为你铸造@运行时,没有类型安全,你应该检查是否object扩展或做之前实现Car,否则你会得到一个异常。 A question I asked ~ a year ago and the answers there也可能与您有关。

虽然,因为别人已经说过,这种气味&你也许可以重新设计以更好的方式,请注意,此类型转换通常会很慢,因为Java需要检查类型层次(它需要如果它不能投射到Car则抛出ClassCastException)。

0

表达式Car.class返回类Carjava.lang.Class对象。

声明Class.forName("Car")也将返回Carjava.lang.Class对象(假设类Car是默认包)。注:不需要追加.class;那会给你ClassClass对象本身,这不是你想要的。

Class有方法来检查对象是否是实例所代表的类的实例(希望这不是太混乱......)。由于您在编译时不知道类Car的名称,因此您不会有任何编译时类型安全性。

查找java.lang.Class的API文档。

1

您正在寻找的是一种名为反射在Java编程语言中的功能。

它允许正在执行的Java程序检查或“反思”自己,并操纵程序的内部属性。例如,Java类可以获取其所有成员的名称并显示它们。

http://java.sun.com

import java.lang.reflect.*; 

    public class DumpMethods { 
     public static void main(String args[]) 
     { 
     try { 
      Class c = Class.forName(args[0]); 
      Method m[] = c.getDeclaredMethods(); 
      for (int i = 0; i < m.length; i++) 
      System.out.println(m[i].toString()); 
     } 
     catch (Throwable e) { 
      System.err.println(e); 
     } 
     } 
    } 

一个简单的示例有关的调用:

java DumpMethods java.util.Stack 

输出为:

public java.lang.Object java.util.Stack.push(
    java.lang.Object) 
    public synchronized 
    java.lang.Object java.util.Stack.pop() 
    public synchronized 
     java.lang.Object java.util.Stack.peek() 
    public boolean java.util.Stack.empty() 
    public synchronized 
    int java.util.Stack.search(java.lang.Object) 

这里是在运行时创建对象的示例:

import java.lang.reflect.*; 

    public class constructor2 { 
     public constructor2() 
     { 
     } 

     public constructor2(int a, int b) 
     { 
     System.out.println(
      "a = " + a + " b = " + b); 
     } 

     public static void main(String args[]) 
     { 
     try { 
      Class cls = Class.forName("constructor2"); 
      Class partypes[] = new Class[2]; 
      partypes[0] = Integer.TYPE; 
      partypes[1] = Integer.TYPE; 
      Constructor ct 
       = cls.getConstructor(partypes); 
      Object arglist[] = new Object[2]; 
      arglist[0] = new Integer(37); 
      arglist[1] = new Integer(47); 
      Object retobj = ct.newInstance(arglist); 
     } 
     catch (Throwable e) { 
      System.err.println(e); 
     } 
     } 
    } 

你可以阅读更多关于它herehere - for indepth view

也看这里: What is reflection and why is it useful?