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文档