作业要求:用控制台控制类方法,实例方法,类变量,实例变量的使用
实现代码如下:
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;
/**
* 方法处理和变量处理的练习 <br>
* 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