Java反射练习
1、通过反射实现动态类加载操作从控制台输入需要加载的类地址:
2、遍历出当前类中的所有属性提示:请输入需要访问的属性:
3、定义设置属性、获取属性值的方法完成后续的属性操作提示:1、设置属性值、2、获取属性值
import java.lang.reflect.Field;
import java.util.Scanner;
public class Work1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
InstantiationException, IllegalAccessException {
Scanner sc = new Scanner(System.in);
Work1 test = new Work1();
System.out.println("请输入类的地址");
String path = sc.next();
// 通过输入的地址拿到该类的对象c
Class c = Class.forName(path);
// 拿到对象c的所有属性
Field[] fds = test.getFields(c, path);
//拿到对象c的实例化对象 如:若输入java.lang.String则为String对象(new String())
Object obj = c.newInstance();
//在循环外定义所选属性值
String content = null;
//定义从控制台输入的属性名
String fieldName = null;
//一个循环使设置完属性值后可以查看是否设置成功
while (true) {
System.out.println(path + "中有以下属性");
//遍历输出用户输入的类的所有属性名
for (Field fd : fds) {
System.out.println(fd.getName());
}
System.out.println("请输入需要访问的属性名:");
//输入属性名
fieldName = sc.next();
System.out.println("请输入:1、设置属性值 2、获取属性值(其他值退出)");
Field fd = c.getField(fieldName);
int i = sc.nextInt();
//用户选择1、设置属性值
if (i == 1) {
System.out.println("请输入需要设置的值:(数据类型为"+fd.getType().getSimpleName()+")");
//用户需要修改的属性值
content = sc.next();
//调用自定义setField()的方法
test.setField(c, fieldName, obj, content);
System.out.println("属性设置完成!");
//用户选择2、获取属性值
} else if (i == 2) {
//调用自定义方法getFieldValue()输出属性值
test.getFieldValue(c, fieldName, obj);
} else {
System.out.println("程序结束~~");
System.exit(0);
}
sc.close();
}
}
public Field[] getFields(Class c, String path) {
//返回所有定义的属性
return c.getDeclaredFields();
}
public void setField(Class c, String fieldName, Object obj, String content)
throws IllegalArgumentException, IllegalAccessException {
Field fd = null;
try {
//拿到用户输入的属性对象
fd = c.getDeclaredField(fieldName);
//将属性对象的修改权限打开(防止属性权限为非公开时不可修改)
fd.setAccessible(true);
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
//拿到用户输入的属性在类中对应的数据类型
String type = fd.getType().getSimpleName();
// System.out.println("属性类型为:"+fd.getType());
// System.out.println("需要更改为:" + content);
// System.out.println("该属性类型为:"+type);
//若该属性的数据类型为int时,使用intTest变量存储用户输入的值
int intTest = 0;
//若该属性的数据类型为char时,使用charTest变量存储用户输入的值
char charTest = 0;
//若该属性的数据类型为boolean时,使用booleanTest变量存储用户输入的值
boolean booleanTest = false;
//若该属性的数据类型为double时,使用doubleTest变量存储用户输入的值
double doubleTest = 0.0;
//如果该属性的数据类型为int
if (type.equals("int")) {
//将输入的数据转换问为int类型
intTest = Integer.parseInt(content);
//修改对象obj的数据
fd.set(obj, intTest);
//将输入的数据转换问为char类型
} else if (type.equals("char")) {
//char类型为字符,所以只拿输入的第一个字符
charTest = Character.valueOf(content.charAt(0));
//修改对象obj的数据
fd.set(obj, charTest);
//将输入的数据转换问为boolean类型
} else if (type.equals("boolean")) {
booleanTest = Boolean.valueOf(content);
//修改对象obj的数据
fd.set(obj, booleanTest);
//将输入的数据转换问为double类型
} else if (type.equals("double")) {
doubleTest = Double.parseDouble(content);
//修改对象obj的数据
fd.set(obj, doubleTest);
//其它都为字符串类型,则不做数据类型转换
} else {
fd.set(obj, content);
}
}
public void getFieldValue(Class c, String fieldName, Object obj)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field fd = null;
//无论权限如何都拿到此属性对象
fd = c.getDeclaredField(fieldName);
//设置为可修改
fd.setAccessible(true);
//输出该对象
System.out.println(fd.get(obj));
// System.out.println(fieldName+"中的值为:"+c.getField(fieldName));
}
}