MethodHandle和VarHandle练习题

作业要求:用控制台控制类方法,实例方法,类变量,实例变量的使用
实现代码如下:

package varHandle76;
/**
 * 
 * @author 吴鹏辉
 *2019年12月13日上午11:30:29
 * @version 1.0
 */
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.util.Scanner;

/**
 * 方法处理和变量处理的练习 
* 2019年12月13日下午1:43:42 * * 使用控制台传入一个类名 方法名 返回值类型 把对应的方法,变量打印出来,输入错误有提示信息 * * @author wcf * @version 1.0 */
public class HandleTest { /** * 程序入口 * * @param args 入口参数 */ public static void main(String[] args) { @SuppressWarnings("resource") Scanner scanner = new Scanner(System.in); System.out.println("请输入目标类的 (变量名) 或者 (类名,方法名,返回值类型),输入多个类型以逗号隔开 " + "\n例如: HandleTest,hello,void"); while (scanner.hasNextLine()) { String str = scanner.nextLine().trim(); if (str.matches("exit|退出")) { System.out.println("退出成功"); break; }else { //对异常进行处理 try { disc(str); } catch (Throwable e) { StackTraceElement [] s=e.getStackTrace(); for (StackTraceElement stackTraceElement : s) { System.out.println(stackTraceElement); } // 对抛出的异常进行处理 System.out.println("输入错误,请重新输入"); continue; } } } } /** * 对输入的字符串进行格式化 * * @param string 输入的字符串 * @throws Throwable 抛出异常 */ private static void disc(String string) throws Throwable { if (string.equals("name")) { // 用findVarHandle方法获取Test类中名为name,类型为String的实例变量 VarHandle varHandle = MethodHandles.lookup().findVarHandle(Test.class, "name", String.class); Test test = new Test(); // 通过VarHandle获取实例变量的值,需要传入对象作为调用者 System.out.println("实例变量name:"+varHandle.get(test)); } else if (string.equals("age")) { // 用findVarHandle方法获取Test类中名为age,类型为int的类变量 VarHandle varHandle1 = MethodHandles.lookup().findStaticVarHandle(Test.class, "age", int.class); // 通过VarHandle获取指定类变量的值 System.out.println("类变量age: " + varHandle1.get()); } else { //使用逗号对输入的字符串进行分割 String[] s = string.split(","); //字符串不能为空,且分割后的长度为3 if (s == null || s.length != 3) { System.out.println("输入错误"); } else if (s[2].equals("void")) { // 使用MethodHandles.Lookup的findStatic获取类方法 MethodHandle methodHandle = MethodHandles.lookup().findStatic(cla(s[0]), s[1], MethodType.methodType(mt(s[2]))); // 通过MethodHandle执行方法 System.out.print("类方法: "); methodHandle.invoke(); } else if (s[2].equals("string")) { // 使用MethodHandles.Lookup的findVirtual获取实例方法 MethodHandle methodHandle1 = MethodHandles.lookup().findVirtual(cla(s[0]), s[1], //指定获取返回值类型为String,形参为String的方法类型 MethodType.methodType(mt(s[2]), String.class)); //通过MethodHandle执行方法,传入主调对象和参数 System.out.println("实例方法: "+methodHandle1.invoke(new Test(), "男")); } else if (s[2].equals("int")) { // 使用MethodHandles.Lookup的findVirtual获取实例方法 MethodHandle methodHandle1 = MethodHandles.lookup().findVirtual(cla(s[0]), s[1], //指定获取返回值类型为int,形参为int的方法类型 MethodType.methodType(mt(s[2]), int.class)); //通过MethodHandle执行方法,传入主调对象和参数 System.out.println("实例方法: "+methodHandle1.invoke(new Test(), 23)); } } } /** * 对输入的类名进行格式化 * * @param string 类名 * @return 格式化结果 */ private static Class<?> cla(String string) { if (string.equals("Test")) { return Test.class; } return null; } /** * 对输入的类型进行格式化 * * @param string 类型 * @return 格式化结果 */ private static Class<?> mt(String string) { if (string.equals("void")) { return void.class; } else if (string.equals("string")) { return String.class; } else if (string.equals("int")) { return int.class; } return null; } }

目标类如下:

package varHandle76;
/**
 * 
 * @author 吴鹏辉
 *2019年12月13日上午11:31:38
 * @version 1.0
 */
public class Test {
	/**
	 * 实例变量
	 */
	String name = "吴鹏辉";
	/**
	 * 类变量
	 */
	static int age = 100;
	/**
	 * 类方法
	 */
	static void name() {
		System.out.println("吴鹏辉要进步");
	}
	/**
	 * 实例方法
	 * @param gender 传入参数
	 * @return 返回值
	 */
	String gender(String gender) {
		System.out.println("执行带参数的gender:" + gender);
		return "性别: " + gender;
	}
	/**
	 * 实例方法
	 * @param age 传入的参数
	 * @return 返回值
	 */
	int age(int age) {
		System.out.println("执行带参数的age:" + age);
		return age;
	}

}

实现效果如下:

请输入目标类的 (变量名) 或者 (类名,方法名,返回值类型),输入多个类型以逗号隔开
例如: HandleTest,hello,void
name
实例变量name:吴鹏辉
age
类变量age: 100
Test,name,void
类方法: 吴鹏辉要进步
Test,gender,string
执行带参数的gender:男
实例方法: 性别: 男
Test,age,int
执行带参数的age:23
实例方法: 23

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