反射机制的应用小场景------看完瞬间理解反射机制
反射机制的神奇
在不用反射机制的情况之下,我们要使用一个类,必须这个类是存在的,在代码角度也是定死的。
但是我们想要调用一个类,这个类在未来才能够定义,我们现在就希望产生这个类的对象,并且调用,我们想要调用的方法。这就用到了反射机制!
我们带入到情景中去看: 用户提供一个xml文件里面包含有,想调用的类,类名,方法,参数(类型,和值),然后想要得到方法执行后的结果。
我们将问题进行总结:
第一步:可以将类名方法名等,通过文件解析出来,并进行处理(因为解析出来都是字符串)。
第二步:用反射机制,生成类对象,并且调用方法,得到结果。
<?xml version="1.0" encoding="UTF-8"?>
<funs>
<fun klass="Zhengshu" method="add">
<para type="int" value="32"></para>
<para type="int" value="32"></para>
</fun>
</funs>
进行解析,一定要注意的是,我们将参数的类型要转化成int.class
double.class类似这样的,值也应该由类型 将字符串转化为相应的值,并且对于多个参数,我们应该用ArrayList存起来。
解析:
`
public class Parse {
static String klass;
static String method;
public final static HashMap<String, Classdefination> h = new HashMap<>();;
public void Jx(String path,String x,String r) throws SAXException, IOException {
new XMLParser() {
@Override
public void dealElement(Element element, int index) {
Classdefination cd=new Classdefination();
cd.setKlass(element.getAttribute("klass"));
cd.setMethod(element.getAttribute("method"));
//将解析出来的字符串set到Parse里面去
//System.out.println(klass+" "+method);
h.put(cd.getKlass(),cd);
//形成HashMap这样键不能重复为类名称,cd放入的是解析的内容
new XMLParser() {
@Override
public void dealElement(Element element, int index) {
Para pa=new Para();
pa.setType(element.getAttribute("type"));
pa.setValue(element.getAttribute("value"));
//System.out.println(type +" "+value);
cd.addA(pa);
//每解析一个para则加入到list里面
}
}.parse(element, "r");
}
}.parse(XMLParser.loadXml("path"),"x");
}
public Classdefination Map(String key) {
return h.get(key);
}
}
进行参数类型和值的处理
//将解析出来的type和value(是字符串类型的)
//转化为原本该有的类型
public class Para {
Class<?> type1;
Object value1;
String type="String";
String value;
public void parameter() {}
private static final HashMap<String,Class> tpval=new HashMap<>() ;
public static void main(String[] args) {
tpval.put("int", int.class);
tpval.put("long", long.class);
tpval.put("short", short.class);
tpval.put("byte", byte.class);
tpval.put("double", double.class);
tpval.put("char", char.class);
tpval.put("boolean", boolean.class);
tpval.put("float",float.class);
System.out.println("123");
}
public Class<?> getType1() {
StringToType(type);
System.out.println(type1);
return type1;
}
public void setType(String type) {
this.type = type;
}
public Object getValue1( ) {
StringToValue(type);
return value1;
}
public void setValue(String value) {
this.value = value;
}
public void StringToType(String type) {
this.type=type;
this.type1=tpval.get(type);
}
public void StringToValue(String type) {
this.type=type;
if(type.equals("String")) {
this.value1=String.valueOf(value);
}
if(type.equals("int")) {
this.value1=Integer.valueOf(value);
}
if(type.equals("float")) {
this.value1=Float.valueOf(value);
}
if(type.equals("byte")) {
this.value1=Byte.valueOf(value);
}
if(type.equals("long")) {
this.value1=Long.valueOf(value);
}
if(type.equals("short")) {
this.value1=Short.valueOf(value);
}
if(type.equals("boolean")) {
this.value1=Boolean.valueOf(value);
}
if(type.equals("char")) {
this.value1=type;
}
}
}
-
这里进行了对字符串化为类型和值的巧妙转化,处理了八大基本类型,若是其他类型,也可以直接在字符串后面直接加.class.
-
还有这里的set方法set的是字符串类型,但是个get返回的类型是是需要的类型!
我们对解析出来的东西要统一归到一个类里面,即将 参数,类型值 处理过后,将他们和类名方法名等放到Classdefination类里面。到时候反射时只从这个类里面去取相应的值。
最后看看运用反射机制的代码
Parse a=new Parse();
a.Jx("/Fun.xml", “fun”, “para”);
Classdefination cd=a.Map(“parseandreflect.Zhengshu”);String klass = cd.getKlass(); String method = cd.getMethod(); Class<?>[] css = new Class[cd.getA().size()] ; Object[] ob = new Object[cd.getA().size()] ; for(int i= 0 ; i<cd.getA().size();i++) { css[i] = cd.getA().get(i).getType1(); //存参数的类型,这个例子里面,它存有两个int.class元素 ob[i] = cd.getA().get(i).getValue1(); //为使用invoke()方法准备参数的值。 } Class<?> klazz = Class.forName(klass); Object obj = klazz.newInstance(); Method me = klazz.getDeclaredMethod(method, css); me.invoke(obj,ob ); System.out.println(me.invoke(obj,ob ));
这样我们就完美的调用了一个未知类的add()方法,是不是感觉很爽呢哈哈!
反射机制就是这样强大!