关于JAVA反射使用

有理想的草根 2009-03-12 10:31:19
小弟在使用Java的反射机制时遇到了一些问题。希望得到大家的帮助。

有两个类一个叫
SymbolBase里面有doPaser方法。
一个SymbolC1继承SymbolBase类,实现自己的一些方法。

而在另一个执行类中。Base类中我在定义的时候定义SymbolBase但是在实例的时候采用SymbolC1。由于有很多个SymbolCX所以需要使用反射根据名称进行实例。


package co.com.comm;

public class Base {

private SymbolBase symbol = null;

public Base(){

symbol = new SymbolC1("String");
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();

}

public static void main(String[] args){
Base base = new Base();
}
}

package co.com.comm;

public class SymbolC1 extends SymbolBase{

public SymbolC1(String strVal) {
super(strVal);
// TODO 自動生成されたコンストラクター・スタブ
}

public void getSymbolStr(){
System.out.print("SymbolC1 getString!");
}
}

package co.com.comm;

public class SymbolBase {
private String strname = "";
public SymbolBase(String strVal){
this.strname = strVal;
}

public void doPaser(){
System.out.println("Base Paser!");
}
}



我的问题是,我想在Base中通过Class.forName来自动根据一个字符串实例化相应的SymbolCX。即SymbolC1,SymbolC2,而且像上面那样使用。
我能想到的是使用Java的反射机制但是具体应该如何实现。看了很多反射实例也没找到方法。
希望高手给予解决,小弟在此谢过。
...全文
290 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
adeng912 2009-03-13
  • 打赏
  • 举报
回复
xuexi
有理想的草根 2009-03-12
  • 打赏
  • 举报
回复
自己写了一种方法但是这种方法是否可取希望大家提出意见。

package co.com.comm;

import java.lang.reflect.Method;

public class Base {

private Class<?> symbol = null;
private Object obj = null;

public Base(){

/*symbol = new SymbolC1("String");
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();*/

try {
symbol = Class.forName("co.com.comm.SymbolC1");

Class[] params = {Class.forName("java.lang.String")};
String[] val = {"Test"};

obj = symbol.getConstructor(params).newInstance(val);

Method method = symbol.getMethod("doPaser", null);

method.invoke(obj, null);

method = symbol.getMethod("getSymbolStr", null);
method.invoke(obj, null);

} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}


}

public static void main(String[] args){
Base base = new Base();
}
}
dawn023 2009-03-12
  • 打赏
  • 举报
回复
一般反射对于设计框架、保证接口扩展性等非常有用,可以保持框架的内聚性,但是稍微影响一点性能。
有理想的草根 2009-03-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 drqdrqdr 的回复:]
newInstance()的那个类必须要有无参数的构造函数,否则实例化失败

package co.com.comm;

public class Base {

private SymbolBase symbol = null;

public Base(String type){

try
{
symbol = (SymbolBase)Class.forName(type).newInstance();
}
catch(Exception e)
{
e.printStackTrace();
}

symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();

}

public static void main(String[] args){…
[/Quote]

前面部分没什么问题。但是在下面执行
symbol.doPaser();((SymbolC1) symbol).getSymbolStr();

部分,即然我都要知道SymbolC1了,我认为我没有必要就使用反射了。我是想所括这部分也是可以使用反射过来的。
有理想的草根 2009-03-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luojihaidao 的回复:]
给个例子, 说说方法怎么用吧。

Class c = Class.forName('className') 得到对就类的Class (带包名 记住了)

c.newInstance() 得到无参的c 一个实例 相当于:new className();
c.getDeclaredConstructor(Class... parameterTypes).newInstance(Object... parameterTypes) 得到带参的c 一个实例; 相当于:new className(参数列表);

c.getDeclaredFields() 得到所有字段。
c.getDeclaredMethods() 得到所有方法。…
[/Quote]
说得很正确,API中也确实有,而且,网上这些资料也不少,但是能不能根据我给出的代码进行使用?
至于我想如何使用,在我给出的代码中Base类里有一个main方法,已经进行了调用。
drqdrqdr 2009-03-12
  • 打赏
  • 举报
回复
newInstance()的那个类必须要有无参数的构造函数,否则实例化失败

package co.com.comm;

public class Base {

private SymbolBase symbol = null;

public Base(String type){

try
{
symbol = (SymbolBase)Class.forName(type).newInstance();
}
catch(Exception e)
{
e.printStackTrace();
}

symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();

}

public static void main(String[] args){
SymbolC1 c1 = new SymbolC1("c1");
Base b = new Base(c1.getClass().getName());
}

}
finingphon 2009-03-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luojihaidao 的回复:]
给个例子, 说说方法怎么用吧。

Class c = Class.forName('className') 得到对就类的Class (带包名 记住了)

c.newInstance() 得到无参的c 一个实例 相当于:new className();
c.getDeclaredConstructor(Class... parameterTypes).newInstance(Object... parameterTypes) 得到带参的c 一个实例; 相当于:new className(参数列表);

c.getDeclaredFields() 得到所有字段。
c.getDeclaredMethods() 得到所有…
[/Quote]

这个挺受用的。
luojihaidao 2009-03-12
  • 打赏
  • 举报
回复
给个例子, 说说方法怎么用吧。

Class c = Class.forName('className') 得到对就类的Class (带包名 记住了)

c.newInstance() 得到无参的c 一个实例 相当于:new className();
c.getDeclaredConstructor(Class... parameterTypes).newInstance(Object... parameterTypes) 得到带参的c 一个实例; 相当于:new className(参数列表);

c.getDeclaredFields() 得到所有字段。
c.getDeclaredMethods() 得到所有方法。
Method m = c.getDeclaredMethod(String name, Class... parameterTypes) 得到指定方法名的方法。 第二个参数是参数列表。

得到方法后:m.invoke(Object obj, Object... args) ; 执行方法, 第一个参数是指定的对象, 第二个是参数列表。

自己总结了一下, 这是常用的。 你看看吧, API上说的很清楚。


luojihaidao 2009-03-12
  • 打赏
  • 举报
回复
看了上面的代码:反射简单的这是这样写的:

public Base(){


try {
symbol = Class.forName("co.com.comm.SymbolC1");

//Class[] params = {Class.forName("java.lang.String")};
//String[] val = {"Test"};

// obj = symbol.getConstructor(params).newInstance(val);
obj = symbol.getConstructor(new Class[]{String.class}).newInstance(new Object[]{"test"});
//这不用Class.forName("java.lang.String")

Method method = symbol.getMethod("doPaser", null);

method.invoke(obj, null);

method = symbol.getMethod("getSymbolStr", null);
method.invoke(obj, null);

} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}


}



还有一点就是:getMethod是有作用域的。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧