java从string加载类

时间:2012-02-19 04:03:21

标签: java classloader

我有需要加载的特定类。名称存储在String数组中。我可以加载特定的类,但我不能完全操纵。

String [] myClassesList = {"Class1", "Class2", "Class3"...};
FileClassLoader loader = new FileClassLoader("MyClassesPath");

Class [] c = new java.lang.Class[myClassesList.length];

for(int i=0; i<myClassesList.length; i++){
     c[i]=loader.loadClass (myClassesList[i]);
     ... //This work proprely
}

但我不能

  c[i] myNewCi = new c[i].<constructor>();

注意:我的所有课程都是JPanel扩展。我需要添加到jTabbedPane。我正在尝试执行以下代码。

...
     myPanelClass myPanel = new myPanelClass();
     jTabbedPane1.addTab("myPanelName", myPanel);
... //This work proprely

任何反馈都会有所帮助。谢谢!

4 个答案:

答案 0 :(得分:2)

如果您只需要让类扩展JPanel以便将其添加到Tab中,请尝试以下操作。

Class<? extends JPanel> c =  Class.forName(myClassesList[i]).asSubclass(JPanel.class);
JPanel panel = c.newInstance();
jTabbedPane1.addTab(panel);

这将创建一个扩展JPanel的新类(使用Reflection),但除非您对其进行类型转换,否则它的功能将受到限制。

如果您决定需要与您的类进行更多交互(调用其他方法等)并且不想进行类型转换,则必须为类定义合约。这意味着在类之间添加一个抽象类,并使抽象类扩展JPanel。这是一个例子。

定义Abstract类。这将在你的课程中有你想要的任何额外的方法名称

public abstract class ATest extends JPanel{
    public abstract String doSomething();
}

然后你必须实现你的具体类

public class Class1 extends ATest{
    public Class1(){
        //init me
    }

    @Override
    public String doSomething() {
        return "Class 2";
    }
}

现在,您可以自由地初始化课程,并使用反射做您喜欢的事情

Class<? extends ATest> c =  Class.forName(myClassesList[i]).asSubclass(ATest.class);
ATest panel = c.newInstance();

System.out.println(panel.doSomething());
jTabbedPane1.addTab(panel);

答案 1 :(得分:1)

您可能希望执行以下操作:

c[i].getConstructor(....).newInstance(....);

....包含相关构造函数参数。

答案 2 :(得分:0)

您想使用Java reflection

答案 3 :(得分:0)

您不能在类对象上调用new,只能在类本身上按名称调用,因为它出现在定义它的代码中。如果您无法以这种方式访问​​该类,则必须使用反射。

供参考:

class MyClass ...

可以使用new进行实例化,但是:

MyClass.class

是表示该类的对象,不能用new实例化。在你的情况下,这个:

MyClass.class.newInstance();

应该足够了。