反射机制的应用小场景------看完瞬间理解反射机制

反射机制的神奇

在不用反射机制的情况之下,我们要使用一个类,必须这个类是存在的,在代码角度也是定死的。
但是我们想要调用一个类,这个类在未来才能够定义,我们现在就希望产生这个类的对象,并且调用,我们想要调用的方法。这就用到了反射机制!

我们带入到情景中去看: 用户提供一个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()方法,是不是感觉很爽呢哈哈!
反射机制就是这样强大!

全部评论

相关推荐

点赞 评论 收藏
分享
牛客101244697号:这个衣服和发型不去投偶像练习生?
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务