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));
	}

}

posted @ 2021-01-15 19:43  阿伦啊  阅读(115)  评论(0编辑  收藏  举报