java反射,从配置⽂件中获取类名、⽅法名、变量、变量类型并进⾏⽅法调⽤
1. 给定类和配置⽂件,利⽤反射调⽤⽅法。
以⼀个Point类和⼀个简单的配置⽂件为例。
Point类和配置⽂件config.properties:
package flect.point;
/**
* Author: Sean
* Date: Created In 21:34 2019/4/15
* Title:
* Description:
* Version: 0.1
* Update History:
* [Date][Version][Author] What has been done;
*/
public class Point {
private int x;
private int y;
private String name;
/**
* ⽆参构造函数
*/
public Point() {
}
/**
* 带x的构造函数
*
* @param x 横坐标
*/
public Point(int x) {
this.x = x;
}
/**
* 带x和y的构造函数
*
* @param x 横坐标
* @param y 纵坐标
*/
public Point(int x, int y) {
this.x = x;
this.y = y;
}
/**
* 带所有参数的构造函数
*
* @param x 横坐标
* @param y 纵坐标
* @param name 名称
*/
public Point(int x, int y, String name) {
this.x = x;
this.y = y;
this.name = name;
}
/**
/**
* 移动点
*
* @param dx ⽔平偏移分量
* @param dy 垂直偏移分量
* @param name 新的名称
*/
public void move(int dx, int dy, String name) {
x += dx;
y += dy;
this.name = name;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + 31;
result = prime * result + 31;
return result;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != Class()) {
return false;
}
Point other = (Point) obj;
return (x == X() && y == Y()); }
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "x: " + x + ", y: " + y + ", name: " + name; }
}
classname=flect.point.Point
method=move
args=12,24,"武汉"
argsType=int,int,String
2. ⾸先需要解决的问题是读取配置⽂件并获得相应的数据
最开始⽤的是ResourceBundle⽅法来读取配置⽂件,但是发现了⼀个很⼤的问题就是中⽂读取出来是乱码,在⽹上查了⼀下,最后⽤InputStream的⽅法解决了,具体代码:
// 读取properties⽂件
Properties properties = new Properties();
InputStream inputStream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("com/part3/reflect/point/config.properties");
try {
if (inputStream == null) {
System.out.println("null input stream");
} else {
properties.load(new InputStreamReader
(inputStream, StandardCharsets.UTF_8));
}
} catch (IOException e) {
System.out.println("读取properties⽂件出错!");
e.printStackTrace();
}
// 从properties⽂件中读取相应的属性
String sClassname = Property("classname");
String[] sArgs = Property("args").split(",");
String[] sArgsType = Property("argsType").split(",");
String sMethod = Property("method");
// 输出检验
System.out.println(sClassname);
System.out.String(sArgs));
System.out.String(sArgsType));
System.out.println(sMethod);
3. 下⼀步需要解决的问题则是根据参数类型获得相应的class
在java反射中,获取method的常⽤⽅法是getMethod,它需要的参数的是⽅法名和该⽅法传⼊参数的类型Class,⽽我们通过properties读取出来的参数类型是⼀个字符串数组,因此我们需要对它进⾏转换,让它返回对应的Class(这⾥只涉及到了基本类型,如果有其他类型也可以⾃⾏添加)。
具体代码如下:
// 根据获取到的参数类型字符串列表转换为相应的Class列表
Class[] oArgsType = new Class[sArgsType.length];
for (int i = 0; i < sArgsType.length; i++) {
oArgsType[i] = getPrimitiveClass(sArgsType[i]);
System.out.println(oArgsType[i].getName());
}
/**
* 根据字符串获取基本类型的class
*
* @param str 基本类型的名称
* @return 基本类型对应的Class
* @return 基本类型对应的Class
*/
private static Class getPrimitiveClass(String str) {
str = LowerCase();
switch (str) {
case "int":
return int.class;
case "double":
return double.class;
case "float":
return float.class;
case "char":
return char.class;
case "string":
return String.class;
default:
System.out.println("undefined!");
return Object.class;
}
}
4. 接下来我们还需要把读取到的字符串参数转换为相应的类型数据并以Object数组的形式保存下来
/
/ 根据参数类型列表将参数转换为相应的类型
Object[] oArgs = new Object[sArgs.length];
for (int i = 0; i < sArgs.length; i++) {
oArgs[i] = transferArguments(sArgsType[i], sArgs[i]);
System.out.println(oArgs[i]);
}
/**
* 根据type将Value转换为相应类型的数据
*
* @param type 数据类型
* @param value 数据
* @return 相应数据的object
*/
private static Object transferArguments(String type, String value) {
type = LowerCase();
switch (type) {
case "int":
return Integer.valueOf(value);
case "double":
return Double.valueOf(value);
case "float":
return Float.valueOf(value);
case "char":
return (Bytes()[0];
case "string":
return value;
default:
System.out.println("undefined!");
return null;
}
}
5. 最后我们就可以根据读取到的“classname"获取它的Class对象并获得它的对应⽅法,传⼊参数进⾏调⽤了
// 根据类名获得它的Class
Class newClass = null;
try {
newClass = Class.forName(sClassname);
} catch (ClassNotFoundException e) {
System.out.println("根据类名初始化类出错!");
}
if (newClass == null) {
System.out.println("类指针为空");
}
/
/ 根据⽅法名获取method
Method method = null;
try {
method = Method(sMethod, oArgsType);
} catch (NoSuchMethodException e) {
System.out.println("未到该⽅法!");
}
// 实例化⼀个对象并对它进⾏⽅法调⽤
Object p = null;
if (method != null) {
try {
p = wInstance();
method.invoke(p, oArgs);
java switch case string} catch (IllegalAccessException | InstantiationException e) { System.out.println("⽣成新实例出错!");
} catch (InvocationTargetException e) {
System.out.println("调⽤⽅法出错!");
}
}
if (p != null) {
System.out.String());
}
最后的输出如下:
完整代码可见github:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论