MethodHandle和VarHandle练习

方法处理和变量处理的练习

练习要求
使用控制台传入一个类名 方法名 返回值类型 把对应的方法,变量打印出来,输入错误有提示信息
使用MethodHandle和VarHandle获取目标类中的实例变量,实例方法和类变量,类方法的信息

效果如下:

1.获取方法
2.获取变量
1
请输入方法名
输入exit或退出,返回上一步
sdfghj
请输入正确的方法名,只可为setAge或setName
setName
带参数的实例方法:小马
小马你好
setAge
不带参数的类方法,年龄是:1
hello baby!
退出
1.获取方法
2.获取变量
2
请输入变量名
dfghjk
请输入正确的变量名,只可为name或age
ghj
请输入正确的变量名,只可为name或age
age
类变量age值为:28
name
实例变量name值为:微笑
exit
1.获取方法
2.获取变量
退出
程序结束,欢迎下次使用

实现思路:先创建一个类变量和一个实例变量,再创建类方法和实例方法,分别为获取方法和获取变量抽象成两个方法来实现,最后在main方法中获取Scanner,调用这两个方法,即可完成,代码如下:

package seven.five;

import java.util.Scanner;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;

/**
 * 用控制台控制类方法,实例方法,类变量,实例变量的使用
 * 
 * @author 张林琛<br>
 * @date 2019/12/14 08:25:53
 * @version 1.0
 */
public class HandleTest {
	// 实例变量
	public String name;
	// 类变量
	public static int age;

	/**
	 * 不带参数的类方法
	 */
	public static void setAge() {
		age++;
		System.out.println("不带参数的类方法,年龄是:" + age);
		System.out.println("hello baby!");
	}

	/**
	 * 带参数和返回值的实例方法
	 * 
	 * @param name 传入的名字
	 * @return 返回结果
	 */
	public String setName(String name) {
		System.out.println("带参数的实例方法:" + name);
		return name + "你好";
	}

	/**
	 * 调用类方法和实例方法
	 * 
	 * @param sc 扫描器对象
	 */
	public static void callMethod(Scanner sc) throws Throwable {
		System.out.println("请输入方法名\n输入exit或退出,返回上一步");
		while (sc.hasNextLine()) {
			String str = sc.nextLine();
			// 判断调用的是哪个方法
			if (str.equals("setAge")) {
				// 定义返回值为void,不带形参的方法类型
				MethodType mt = MethodType.methodType(void.class);
				// 使用MethodHandles.lookup()的findStatic()获取类方法
				MethodHandle mh = MethodHandles.lookup().findStatic(HandleTest.class, "setAge", mt);
				// 通过MethodHandle执行方法
				mh.invoke();
			} else if (str.equals("setName")) {
				// 使用MethodHandles.Lookup的findVirtual获取实例方法
				MethodHandle mh2 = MethodHandles.lookup().findVirtual(HandleTest.class, "setName",
						// 指定获取返回值类型为String,形参为String的方法类型
						MethodType.methodType(String.class, String.class));
				// 通过MethodHandle执行方法,传入主调对象和参数
				System.out.println(mh2.invoke(new HandleTest(), "小马"));
				continue;
			} else if (str.equals("退出") || str.equals("exit")) {
				return;
			} else {
				System.out.println("请输入正确的方法名,只可为setAge或setName");
			}

		}
	}

	/**
	 * 调用变量
	 * 
	 * @param sc 扫描器对象
	 */
	public static void callVar(Scanner sc) throws NoSuchFieldException, IllegalAccessException {
		System.out.println("请输入变量名");
		while (sc.hasNextLine()) {
			String str = sc.nextLine();
			// 判断调用的是哪个方法
			if (str.equals("name")) {
				// 用findVarHandle方法获取HandleTest类中名为name,类型为String的实例变量
				VarHandle vh = MethodHandles.lookup().findVarHandle(HandleTest.class, "name", String.class);
				// 创建当前类对象
				HandleTest ht = new HandleTest();
				// 为实例变量赋值
				vh.set(ht, "微笑");
				// 输出实例变量
				System.out.println("实例变量name值为:" + ht.name);
			} else if (str.equals("age")) {
				// 用findVarHandle方法获取HandleTest类中名为age,类型为int的类变量
				VarHandle vh1 = MethodHandles.lookup().findStaticVarHandle(HandleTest.class, "age", int.class);
				// 通过VarHandle设置指定类变量的值
				vh1.set(28);
				// 输出User的MAX_AGE类变量
				System.out.println("类变量age值为:" + HandleTest.age);
			} else if (str.equals("退出") || str.equals("exit")) {
				return;
			} else {
				System.out.println("请输入正确的变量名,只可为name或age");
			}
		}
	}

	/**
	 * 程序入口
	 * 
	 * @param args
	 * @throws Throwable
	 */
	public static void main(String[] args) throws Throwable {
		Scanner sc = new Scanner(System.in);
		System.out.println("1.获取方法\n2.获取变量");
		while (sc.hasNextLine()) {
			String str = sc.nextLine();
			if (str.equals("1")) {
				// 如果输入1,则调用获取方法
				HandleTest.callMethod(sc);
			} else if (str.equals("2")) {
				// 如果输入2,则调用获取变量
				HandleTest.callVar(sc);
			} else if (str.equals("退出") || str.equals("exit")) {
				System.out.println("程序结束,欢迎下次使用");
				break;
			} else {
				System.out.println("请输入对应的选项");
			}
			System.out.println("1.获取方法\n2.获取变量");
		}
	}
}

这是对MethodHandle和VarHandle最简单的用法,更多用法请参考API!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值