MethodHandle和VarHandle练习

MethodHandle和VarHandle练习

方法处理和变量处理的练习
练习要求
使用控制台传入一个类名 方法名 返回值类型 把对应的方法,变量打印出来,输入错误有提示信息

使用MethodHandle和VarHandle获取目标类中的实例变量,实例方法和类变量,类方法的信息
得到效果

通过输入指令进行调用:
1:调用实例变量
2:调用类变量
3:调用实例方法
4:调用类方法
exit:退出
1
请输入要调取的变量名,或exit退出
hello
请输入正确的变量名
name
name变量的值为:实例变量
请输入变量名继续操作,或exit退出

具体代码实现:

public class MethodHandleTest {
	/**
	 * 实例变量
	 */
	public String name = "实例变量";

	/**
	 * 类变量
	 */
	public static String staticname = "类变量";

	// 定义一个public类方法
	public static void hello() {
		System.out.println("Hello world!");
	}

	// 定义一个public实例方法
	public String hello(String name) {
		System.out.println("执行带参数的hello:" + name);
		return name + "java";
	}

}
public class Dcs {
	/**
	 * 扫描器对象
	 */
	static Scanner sc = new Scanner(System.in);

	/**
	 * 总控制方法
	 * 
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 */
	public static void tmm() {
		System.out.println("通过输入指令进行调用:\n1:调用实例变量\n2:调用类变量\n3:调用实例方法\n4:调用类方法\nexit:退出");
		while (sc.hasNextLine()) {
			String string = (String) sc.nextLine();
//			判断是否为空
			if (string == null) {
				System.out.println("输入错误请重新输入");
				continue;
			}

//			判断指令
			switch (string) {
			case "1":
				instanceVariable();
				break;
			case "2":
				classVariables();
				break;
			case "3":
				instanceMethod();

				break;
			case "4":
				classMethods();
				break;
			case "exit":
				System.out.println("程序退出成功");
//				结束程序
				System.exit(0);
				break;
			default:
				System.out.println("输入错误请重新输入");
				break;
			}

		}
	}

	/**
	 * 处理实例变量的方法
	 * 
	 */
	public static void instanceVariable() {
		System.out.println("请输入要调取的变量名,或exit退出");
		while (sc.hasNext()) {
			String string = (String) sc.next();
			if (string == null) {
				System.out.println("输入不可为null");
				continue;
			} else if (string.equals("exit")) {
				System.out.println("退出成功");
//				结束程序
				System.exit(0);
			} else {
				try {
					// 用findVarHandle方法获取MethodHandleTest类中名为stringf,类型为String的实例变量
					VarHandle varHandle2 = MethodHandles.lookup().findVarHandle(MethodHandleTest.class, string,
							String.class);
//				创建MethodHandleTest类对象
					MethodHandleTest mtHandleTest = new MethodHandleTest();
					// 通过VarHandle获取实例变量的值,需要传入对象作为调用者
					System.out.println(string + "变量的值为:" + varHandle2.get(mtHandleTest));
					System.out.println("请输入变量名继续操作,或exit退出");
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("请输入正确的变量名");
				}

			}

		}

	}

	/**
	 * 处理类变量的方法
	 * 
	 */
	public static void classVariables() {
		System.out.println("请输入要调取的变量名,或exit退出");
		while (sc.hasNext()) {
			String string = (String) sc.next();
			if (string == null) {
				System.out.println("输入不可为null");
				continue;
			} else if (string.equals("exit")) {
				System.out.println("退出成功");
//				结束程序
				System.exit(0);
			} else {
				try {
					// 用findVarHandle方法获取MethodHandleTest类中名为string,类型为String的类变量
					VarHandle varHandle3 = MethodHandles.lookup().findStaticVarHandle(MethodHandleTest.class, string,
							String.class);
					// 输出MethodHandleTest的string类变量
					System.out.println(string + "变量的值为:" + varHandle3.get());
					System.out.println("请输入变量名继续操作,或exit退出");
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("请输入正确的变量名");
				}

			}

		}

	}

	/**
	 * 处理实例方法
	 */
	public static void instanceMethod()  {
//		存储获取到的参数
		String[] aStrings;
		System.out.println("请输入要调取的方法名和形参,以逗号分隔,或exit退出");
		while (sc.hasNext()) {
			String string = (String) sc.next();
			if (string == null) {
				System.out.println("输入不可为null");
				continue;
			} else if (string.equals("exit")) {
				System.out.println("退出成功");
//				结束程序
				System.exit(0);
			} else {
//				分隔字符串
				aStrings = string.split(",");
				try {
					// 使用MethodHandles.Lookup的findVirtual获取实例方法
					MethodHandle methodHandle2 = MethodHandles.lookup().findVirtual(MethodHandleTest.class, aStrings[0],
					// 指定获取返回值类型为String,形参为String的方法类型
					MethodType.methodType(String.class, String.class));
					// 通过MethodHandle执行方法,传入主调对象和参数
					System.out.print(aStrings[0]+"方法开始执行:");
					String a=(String) methodHandle2.invoke(new MethodHandleTest(), aStrings[1]);
					System.out.println("返回值是:"+a);
					System.out.println("请继续输入要调取的方法名和形参,以逗号分隔,或exit退出");
				} catch (Exception e) {
					System.out.println("请输入正确的方法名和形参");
				} catch (Throwable e) {
					
				}

			}

		}

	}
	/**
	 * 处理类方法
	 * 
	 */
	public static void classMethods()  {

		System.out.println("请输入要调取的方法名,或exit退出");
		while (sc.hasNext()) {
			String string = (String) sc.next();
			if (string == null) {
				System.out.println("输入不可为null");
				continue;
			} else if (string.equals("exit")) {
				System.out.println("退出成功");
//				结束程序
				System.exit(0);
			} else {

				try {
			        // TODO Auto-generated method stub
			        // 定义一个返回值为void,不带形参的方法类型,void.class首字母小写
			        MethodType methodType = MethodType.methodType(void.class);
			        // 使用MethodHandles.Lookup的findStatic获取类方法
			        MethodHandle methodHandle = MethodHandles.lookup().findStatic(MethodHandleTest.class,string, methodType);
			        // 通过MethodHandle执行方法
			        methodHandle.invoke();
					System.out.println("请继续输入要调取的方法名,或exit退出");
				} catch (Exception e) {
					System.out.println("请输入正确的方法名");
				} catch (Throwable e) {
					
				}

			}

		}

	}


}
public class Test {
	public static void main(String[] args) {
			Dcs.tmm();
	}
}

简单的实现下MethodHandle和VarHandle用法,具体操作请查阅API文档

你可能感兴趣的:(MethodHandle和VarHandle练习)