简单例子

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;public class MHT {private String name;// 构造方法public MHT(String name) {this.name = name;}// 公共方法public String publicTest() {return name + "'publicTest";}// 静态方法public static String publicStaticTest() {return "'publicStaticTest";}// 私有方法private String test(int param) {switch (param) {case 1:return "suych1";case 2:return "suych2";case 3:return "suych3";default:return "suych4";}}// Get方法public String getName() {return name;}// Set方法public void setName(String name) {this.name = name;}public static void main(String[] args) throws Throwable {// 构造方法MethodType mtConstructor = MethodType.methodType(void.class, String.class);  //返回值类型,参数类型MethodHandle mhConstructor = MethodHandles.lookup().findConstructor(MHT.class, mtConstructor);MHT businessHandle = ( MHT ) mhConstructor.invokeExact("suych");System.out.println(businessHandle.getName());// 公共方法MethodType mtPublic = MethodType.methodType(String.class);  //返回值类型MethodHandle mhPublic = MethodHandles.lookup().findVirtual(MHT.class, "publicTest", mtPublic);String resultPublic = ( String ) mhPublic.invokeExact(businessHandle);System.out.println(resultPublic);// 静态方法MethodType mtPublicStatic = MethodType.methodType(String.class);MethodHandle mhPublicStatic = MethodHandles.lookup().findStatic(MHT.class, "publicStaticTest",mtPublicStatic);String resultPublicStatic = ( String ) mhPublicStatic.invokeExact();System.out.println(resultPublicStatic);// 私有方法MethodType mtPrivate = MethodType.methodType(String.class, int.class); //返回值类型,参数类型MethodHandle mhPrivate = MethodHandles.lookup().findSpecial(MHT.class, "test", mtPrivate,MHT.class);String resultPrivate = ( String ) mhPrivate.invokeExact(businessHandle, 1);System.out.println(resultPrivate);// Set方法MethodHandle mhSet = MethodHandles.lookup().findSetter(MHT.class, "name", String.class);mhSet.invokeExact(businessHandle, "A");System.out.println(businessHandle.name);// Get方法MethodHandle mhGet = MethodHandles.lookup().findGetter(MHT.class, "name", String.class);String resultGet = ( String ) mhGet.invokeExact(businessHandle);System.out.println(resultGet);}}

输出:

suych   构造方法输出
suych'publicTest   公共方法输出
'publicStaticTest   静态方法输出
suych1   私有方法输出
A   Set方法输出
A   Get方法输出

基于MethodHandle实现的调用Runtime执行系统命令

import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Scanner;/*** @author yz*/
public class MethodHandlesTest {public static void main(String[] args) {try {String               str          = "arp -a";Class                runtimeClass = Runtime.class;MethodHandles.Lookup lookup       = MethodHandles.lookup();// Runtime rt = Runtime.getRuntime()MethodHandle methodHandle = lookup.findStatic(runtimeClass, "getRuntime", MethodType.methodType(runtimeClass));// 获取Runtime的exec方法MethodHandle execMethod = lookup.findVirtual(runtimeClass, "exec", MethodType.methodType(Process.class, new Class[]{String.class}));// 获取Process的getInputStream方法MethodHandle inputStreamMethod = lookup.findVirtual(Process.class, "getInputStream", MethodType.methodType(InputStream.class));// 调用Runtime.getRuntime().exec(xxx).getInputStream()InputStream in = (InputStream) inputStreamMethod.invoke(execMethod.invoke(methodHandle.invoke(), str));// 输出InputStream内容到Scanner scanner = new Scanner(in).useDelimiter("\\A");System.out.println(scanner.hasNext() ? scanner.next() : "");} catch (Throwable t) {t.printStackTrace();}}}

JAVA反射修改private,final值

FinalName.java

class FinalName {public final String name="init";
}

PrivateName.java

class PrivateName {private String name = "init";public String getName() {return name;}
}

Test.java

import java.lang.reflect.Field;public class Test {public static void main(String[] args) throws Exception {PrivateName privateName = new PrivateName();FinalName finalName = new FinalName();
//        System.out.println(finalName.name);modify(privateName, "name", "private change");modify(finalName, "name", "final change");System.out.println(privateName.getName());System.out.println(finalName.name);}public static void modify(Object object, String fieldName, Object newFieldValue) throws Exception {Field field = object.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(object, newFieldValue);System.out.println(field.get(object));}
}

输出结果,private修饰的变量结果已经被修改,但是final修改正常但是获取的依然是原先的值,这是因为内联优化。

private change
final change
private change
init

如果将FinalName.java修改为通过构造方法给final修饰的属性赋值。

class FinalName {public final String name;FinalName(String name) {this.name = name;}
}
FinalName Finalname = FinalName("aaaaaa");

再次运行Test.java,发现final修饰的变量已经被修改。

private change
final change
private change
final change

总结:private修饰的变量可以通过反射的方法将值修改,需要设置访问权限为true。field.setAccessible(true);
final修饰的变量如果是直接赋值,则对属性值进行修改无效。如果是通过构造方法修改属性的值,则可以通过反射的方法修改final修饰的变量。

通过反射方式执行命令。

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Scanner;
public class ReflectionTest {public static void exec() {try {System.out.println(Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "curl -i localhost:8000"));} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {try {String str = "arp -a";// java.lang.RuntimeString runtime = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101});// Runtime.classClass<?> c = Class.forName(runtime);// 获取getRuntime方法,Runtime.getRuntime()Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));// 获取Runtime的exec方法,rt.exec(xxx)Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);// Runtime.getRuntime().exec(str)Object obj2 = m2.invoke(m1.invoke(null), str);// 获取命令执行结果Process类的getInputStream()方法Method m = obj2.getClass().getMethod(new String(new byte[]{103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109}));m.setAccessible(true);// process.getInputStream()InputStream in = (InputStream) m.invoke(obj2, new Object[]{});// 输出InputStream内容到Scanner scanner = new Scanner(in).useDelimiter("\\A");System.out.println(scanner.hasNext() ? scanner.next() : "");} catch (Throwable t) {t.printStackTrace();}}}

看下为什么获取命令执行结果Process类的getInputStream()方法访问权限需要设置true。
跟入java.lang.ProcessImpl类

getInputStream方法返回stdout_stream是私有变量


注释掉,则会报下面这样的错误

参考链接:
https://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodType.html
https://mp.weixin.qq.com/s/mlqjOlhefcsO9z51cw4S7w
https://blog.csdn.net/yhd723948277/article/details/82661870

转载于:https://www.cnblogs.com/afanti/p/11090072.html

# JDK7+ MethodHandle相关推荐

  1. methodhandle_概览Java 7 MethodHandle及其用法

    methodhandle 由于Java的Reflection API,我们已经能够在运行时检查和更改程序执行. 特别是,我们可以在运行时观察接口/类/方法和字段,而无需在编译时知道它们的名称. JDK ...

  2. 速览Java 7 MethodHandle及其用法

    由于Java的Reflection API,我们已经能够在运行时检查和更改程序执行. 特别是,我们可以在运行时观察接口/类/方法和字段,而在编译时不知道它们的名称. JDK 7为这种动态/运行时检查引 ...

  3. 【JDK7】新特性(2) 语法

    2019独角兽企业重金招聘Python工程师标准>>> JDK7对Java语法有少量更新,重点是在易用性和便捷性的改进.     1.二进制字面量 JDK7开始,终于可以用二进制来表 ...

  4. jdk7新特性学习笔记

    jdk7新特性学习笔记 从网络down了视频看,记录下学过的东西. 1.二进制字面量 JDK7开始,可以用二进制来表示整数(byte,short,int和long),语法:在二进制数值前面加 0b或者 ...

  5. 不止JDK7的HashMap,JDK8的ConcurrentHashMap也会造成CPU 100%

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:朱小厮 公众号:朱小厮的博客(ID:hiddenkafka) ...

  6. java 8代码 改 java7_Window安装JDK7和JDK8,并一键切换

    脚本代码:(保存成.bat文件直接运行就可以了.)代码如下: @echo off title 修改JDK mode con cols=35 lines=20 color 3f cd /d " ...

  7. String.intern()方法JDK6与JDK7/JDK8不同

    在JDK6中,String.intern()方法先去运行时常量池中查看有无该字符串,如果有,则直接返回该字符串在方法区的内存地址.如果没有则会先将该字符串对象复制一份保存在常量池中,并返回该字符串对象 ...

  8. 【CENTOS6】ORACLE JDK7安装

    2019独角兽企业重金招聘Python工程师标准>>> 介绍 在CENTOS上安装JDK是很多应用的前提,所以这里讲JDK安装配置分享一下,由于32位JDK在gc优化上有着不错的性能 ...

  9. JDK7 AIO介绍

    1. JDK7 AIO初体验 JDK7已经release一段时间了,有个重要的新特性是AIO.今天趁闲暇,简单体验了下,简单分享如下: 2. 关于AIO的概念理解 关于AIO的概念,仅谈谈个人的一点理 ...

  10. CentOS下安装JDK7 转载

    转载地址:http://www.cnblogs.com/rilley/archive/2012/02/02/2335395.html CentOS下安装JDK7 下载地址:http://www.ora ...

最新文章

  1. 改变shell read命令的隔符
  2. iOS 修改textholder的颜色
  3. python xpath语法-Python爬虫——bs4、xpath基本语法
  4. 弹簧压缩 时间 matlab,用matlab解决弹簧振子摆动与时间的关系
  5. 前端学习(2733):重读vue电商网站43之使用 lodash 中 cloneDeep(obj) 来实现深拷贝
  6. Linux进程全解7——父进程wait / waitip回收子进程
  7. linux中强大且常用命令:find、grep
  8. server 2008 跨进新的平台(二)
  9. 阿里巴巴港股股价创历史新高 市值超6.1万亿港元
  10. redis 系列24 哨兵Sentinel (中)
  11. 201521123009 《Java程序设计》第1周学习总结
  12. php mysql表单源码_PHP表单数据写入MySQL数据库的代码
  13. SCCM2012系列之十,SCCM2012软件分发
  14. Zalo电脑版多开软件
  15. 变位齿轮重合度计算公式_求变位齿轮的变位系数计算公式。
  16. (ChibiOS )嵌入式操作系统 与 (OSAL)操作系统抽象层
  17. OSN 7500 智能光交换系统是继承了MSTP技术的全部特点
  18. 百度信息流 绑定服务器,【实例】百度信息流账户搭建步骤
  19. RNN分类IMDB电影评分
  20. 从零开始设计RISC-V处理器——五级流水线之控制冒险

热门文章

  1. 分享一次学习中遇到的问题
  2. Android - Broadcast机制
  3. 5月17日 AJAX之JSON
  4. 【Tyvj】1473校门外的树3 线段树/树状数组 区间修改+单点访问
  5. C#中object sender与EventArgs e
  6. JAVA随机数生成 | Math.random()方法 | 随机生成int、double类型
  7. 解决响应式布局border带来的麻烦
  8. 40. 数组中只出现一次的数字(C++版本)
  9. jmeter正则表达式提取器_jmeter压测学习4正则表达式提取
  10. 论文英文参考文献[10]的时候后面多空格_毕业生必看论文查重修改技巧