Java学习笔记一MethodHandle和VarHandle_methodhandle 和 varhandle-程序员宅基地

技术标签: Java  java  

Java 9增强的MethodHandle

MethodHandle为Java增加了方法引用的功能,方法引用的概念有点类似于C的函数指针。这种方法引用是一种轻量级的引用方式,它不会检查方法的访问权限,也不管方法所属的类、实例方法或静态方法,MethodHandle就是简单代表特定的方法,并可通过MethodHandle来调用方法。
MethodHandles是MethodHandle的工厂类,它提供了一系列静态方法用于获取MethodHandle。MethodHandles.Lookup静态内部类也是MethodHandle、VarHandle的工厂类,专门用于获取MethodHandle和VarHandle。MethodType代表一个方法类型,根据方法的形参、返回值类型来确定方法类型。

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class MethodHandleTest {
    
    // 定义一个private类方法
    private static void hello(){
     System.out.println("hello world!"); }
    // 定义一个private实例方法
    private String hello(String name) {
     System.out.println("执行带参数的hello"+name); return name+",您好"; }
    public static void main(String[] args) throws Throwable{
    
        // 定义一个返回值值为void、不带形参的方法类型
        MethodType type = MethodType.methodType(void.class);
        // 使用MethodHandles.Lookup的findStatic获取类方法
        MethodHandle mtd = MethodHandles.lookup().findStatic(MethodHandleTest.class, "hello", type);
        // 通过MethodHandle执行方法
        mtd.invoke();

        // 使用MethodHandles.Lookup的findVirtual获取实例方法                                            指定获取返回值为String、形参为String的方法类型
        MethodHandle mtd2 = MethodHandles.lookup().findVirtual(MethodHandleTest.class, "hello", MethodType.methodType(String.class, String.class));
        System.out.println(mtd2.invoke(new MethodHandleTest(), "孙空"));
    }
}

在这里插入图片描述

Java 9增强的VarHandle

VarHandle主要用于动态操作数组的元素或对象的成员变量。VarHandle与MethodHandle非常类似,它也需要通过MethodHandles来获取实例,接下来调用VarHandle的方法即可动态操作指定数组的元素或指定对象的成员变量。

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Arrays;

class User{
    
    String name;
    static int MAX_AGE;
}
public class VarHandleTest {
    
    public static void main(String[] args) throws Throwable{
    
        String[] sa = new String[]{
    "Java", "Kotlin", "Go"};
        // 获取一个String[]数组的VarHandle对象
        VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
        // 比较并设置:如果第三个元素是Go,则该元素被设置为Lua
        boolean r = avh.compareAndSet(sa, 2, "Go", "Lua");
        System.out.println(r);
        // 看到第三个元素被替换为Lua
        System.out.println(Arrays.toString(sa));
        // 获取sa数组的第二个元素
        System.out.println(avh.get(sa,1));
        // 获取并设置:返回第三个元素,并将第三个元素设置为Swift
        System.out.println(avh.getAndSet(sa, 2, "Swift"));
        // 看到第三个元素被替换成Swift
        System.out.println(Arrays.toString(sa));

        //用findVarHandle方法获取User类中名为name类型为String的实例变量
        VarHandle vh = MethodHandles.lookup().findVarHandle(User.class, "name", String.class);
        User user = new User();
        // 通过VarHandle获取实例变量的值,需要传入对象作为调用者
        System.out.println(vh.get(user)); // 输出null
        // 通过VarHandle设置指定实例变量的值
        vh.set(user, "悟空");
        // 输出user的name实例变量的值
        System.out.println(user.name);

        // 用findVarHandle方法获取User类中名为MAX_AGE类型为Integer的类变量
        VarHandle vh1 = MethodHandles.lookup().findStaticVarHandle(User.class, "MAX_AGE", int.class);
        // 通过VarHandle获取类变量的值
        System.out.println(vh1.get()); // 输出0
        // 通过VarHandle设置指定类变量的值
        vh1.set(100);
        // 输出user的MAX_AGE类变量的值
        System.out.println(User.MAX_AGE);
    }
}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/asmartkiller/article/details/104993330

智能推荐

请求模块urllib的基本使用_with open 保存图片-程序员宅基地

文章浏览阅读3.2k次,点赞54次,收藏78次。在实现网络爬虫的爬取工作时,就必须使用网络请求,只有进行了网络请求才可以对响应结果中的数据进行提取,urllib模块是python自带的网络请求模块,无需安装,导入即可使用。下面将介绍如果使用python中的urllib模块实现网络请求_with open 保存图片

Android底层JNI中的JavaVM和JNIEnv对象_jnivlzm-程序员宅基地

文章浏览阅读1.2k次。最近在做关于安卓安全方面的东西,需要对底层进行注入,在看雪论坛上看了不少资料,查阅了相关书籍了解了一下,需要用到JNI。利用JNI可以实现Java和底层的C/C++模块相互沟通(NDK的框架用到了该外观设计模式,Facade Pattern) 其具体步骤如下:(1)创建一个包含native本地方法的类;(2)利用javah工具生成C/C++语言的头文件;(3)创建.c源文件,使用C/C++实_jnivlzm

RSA算法进行 数据加解密 与 数字签名、哈希(Hash) 摘要_哈希算法与rsa算法-程序员宅基地

文章浏览阅读485次,点赞9次,收藏6次。RSA算法进行 数据加解密 与 数字签名;_哈希算法与rsa算法

HTML、CSS、JS实现轮播图效果:包含分页按钮及切换箭头_html轮播图添加左右箭头-程序员宅基地

文章浏览阅读3.2k次。HTML、CSS、JS实现轮播图效果:包含分页按钮及切换箭头_html轮播图添加左右箭头

Android渲染(一)------ Shader之SweepGradient用法(雷达扫描效果)_android sweepgradient-程序员宅基地

文章浏览阅读707次。Shader定义:官方的定义是这样的: Shader是返回水平跨度颜色的对象的基类,绘图期间。 Shader的子类安装在Paint调用中,paint.setShader(着色器)。 之后的任何对象(除了位图之外)都是使用该绘制绘制将从着色器获取其颜色。它有五个子类,分别是:SweepGradient、LinearGradient、BitmapShader、Compose..._android sweepgradient

no2222_通信emm substate-程序员宅基地

文章浏览阅读530次。222_通信emm substate

随便推点

Error:Internal error: (java.io.FileNotFoundException) D:\code\project\.idea\misc.xml (The sys-程序员宅基地

文章浏览阅读1.6k次。 Intellij idea找不到misc.xml文件,关闭当前项目IDE,重新打开idea, File -> import project,即可重新生成该文件_error:internal error: (java.io.filenotfoundexception)

每日模板一练——并查集-程序员宅基地

文章浏览阅读129次。洛谷2814极度细(毒)节(瘤)的字符串处理,以及最后一步弄错。。。。。(水了70分?)【代码~】 #include<bits/stdc++.h>using namespace std;const int MAXN=5e4+10;map<string,int> name;map<int,string> id;map<string...

生成报表(转)-程序员宅基地

文章浏览阅读123次。使用JasperReport+iReport进行WEB开发    一、JasperReport和iReport简介:   1、JasperReport简介   JasperReport是一个强大、灵活的报表生成工具,是开放源代码组织sf.net中的...

哈希表-程序员宅基地

文章浏览阅读3k次,点赞5次,收藏18次。初入数据结构的哈希表(Hash Table)这次我们来总结一下关于哈希表的知识,首先我们要了解什么是哈希表,哈希函数的构造思路有哪些?怎么解决哈希冲突?最后再去分析一下哈希查找算法。哈希表的概念 前提小知识什么是哈希表?哈希表的四个概念关键字、值、哈希函数、哈希地址、哈希表之间的关系?什么是哈希冲突常见的哈希函数构造方法 怎么样才是好的哈希函数?常见构建哈希函数的六个方法...

VS报错 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义 链接报错: 错误 33 error LNK2005: _DllMai_error lnk2005: _dllmain@12 已经在 msvcrtd.lib(dll_dll-程序员宅基地

文章浏览阅读584次。VS报错 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义链接报错:错误 33 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义 E:\客户问题\w_王鹏\EventLibTest_TibrvAlternative_Mult_error lnk2005: _dllmain@12 已经在 msvcrtd.lib(dll_dllmain_stub.obj) 中定义

什么是soap_soap是指什么-程序员宅基地

文章浏览阅读645次。SOAP (Simple Object Access Protocol) 顾名思义,是一个严格定义的信息交换协议,用于在Web Service中把远程调用和返回封装成机器可读的格式化数据。事实上SOAP数据使用XML数据格式,定义了一整套复杂的标签,以描述调用的远程过程、参数、返回值和出错信息等等。而且随着需要的增长,又不得增加协议以支持安全性,这使SOAP变得异常庞大,背离了简单的初衷。另一方面,各个服务器都可以基于这个协议推出自己的API,即使它们提供的服务及其相似,定义的API也不尽相同,这又导致.._soap是指什么