• Java 15 新特性:隐藏类


    什么是隐藏类

    隐藏类,是一种不能被其他类直接使用的类。引入隐藏类的主要目的是给框架来使用,使得框架可以在运行时生成类,并通过反射间接使用它们。可能有点抽象,不要紧,下面我们通过一个例子来直观的认识它!

    隐藏类案例

    第一步:先创建一个普通的Java类

    public class JEP371HiddenClasses {
    
        public static String hello() {
            return "https://www.didispace.com";
        }
    
    }
    

    第二步:编译一下,或得编译后的class文件。然后使用Base64对文件内容Encode,你可以用各种工具,也可以用下面代码来获取:

    String filePath = "JEP371HiddenClasses.class";
    byte[] b = Files.readAllBytes(Paths.get(filePath));
    log.info(Base64.getEncoder().encodeToString(b));
    

    执行一下,获取到内容如下:

    yv66vgAAAD0AFAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCAAIAQAZaHR0cHM6Ly93d3cuZGlkaXNwYWNlLmNvbQcACgEALmNvbS9kaWRpc3BhY2UvZGVidWcvamF2YTE1L0pFUDM3MUhpZGRlbkNsYXNzZXMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAMExjb20vZGlkaXNwYWNlL2RlYnVnL2phdmExNS9KRVAzNzFIaWRkZW5DbGFzc2VzOwEABWhlbGxvAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAApTb3VyY2VGaWxlAQAYSkVQMzcxSGlkZGVuQ2xhc3Nlcy5qYXZhACEACQACAAAAAAACAAEABQAGAAEACwAAAC8AAQABAAAABSq3AAGxAAAAAgAMAAAABgABAAAAAwANAAAADAABAAAABQAOAA8AAAAJABAAEQABAAsAAAAbAAEAAAAAAAMSB7AAAAABAAwAAAAGAAEAAAAGAAEAEgAAAAIAEw==
    

    这个内容就是第一步写的类。

    第三步:通过反射加载上面生成的类,并调用隐藏类中的hello函数,代码如下:

    /**
     * 程序猿DD
     * <a href="https://www.didispace.com/java-features/">Java新特性解读</a>
     */
    @Test
    void testHiddenClasses() throws Throwable {
      // 1. 加载encode之后的隐藏类
      String CLASS_INFO = "yv66vgAAAD0AFAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCAAIAQAZaHR0cHM6Ly93d3cuZGlkaXNwYWNlLmNvbQcACgEALmNvbS9kaWRpc3BhY2UvZGVidWcvamF2YTE1L0pFUDM3MUhpZGRlbkNsYXNzZXMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAMExjb20vZGlkaXNwYWNlL2RlYnVnL2phdmExNS9KRVAzNzFIaWRkZW5DbGFzc2VzOwEABWhlbGxvAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAApTb3VyY2VGaWxlAQAYSkVQMzcxSGlkZGVuQ2xhc3Nlcy5qYXZhACEACQACAAAAAAACAAEABQAGAAEACwAAAC8AAQABAAAABSq3AAGxAAAAAgAMAAAABgABAAAAAwANAAAADAABAAAABQAOAA8AAAAJABAAEQABAAsAAAAbAAEAAAAAAAMSB7AAAAABAAwAAAAGAAEAAAAGAAEAEgAAAAIAEw==";
      byte[] classInBytes = getDecoder().decode(CLASS_INFO);
      Class<?> proxy = MethodHandles.lookup()
        .defineHiddenClass(classInBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE)
        .lookupClass();
    
      // 输出类名
      log.info(proxy.getName());
      // 输出类有哪些函数
      for(Method method : proxy.getDeclaredMethods()) {
        log.info(method.getName());
      }
      // 2. 调用hello函数
      MethodHandle mh = MethodHandles.lookup().findStatic(proxy, "hello", MethodType.methodType(String.class));
      String result = (String) mh.invokeExact();
      log.info(result);
    }
    

    具体执行逻辑就不啰嗦了,读者可以根据注释来理解。最后执行这个测试内容,可以获得如下输出:

    17:20:50.360 [main] INFO com.didispace.debug.java15.JEP371Test - com.didispace.debug.java15.JEP371HiddenClasses/0x0000000800cb0c00
    17:20:50.361 [main] INFO com.didispace.debug.java15.JEP371Test - hello
    17:20:50.361 [main] INFO com.didispace.debug.java15.JEP371Test - https://www.didispace.com
    
    • 第一行:输出了这个隐藏类的类名
    • 第二行:输出了这个隐藏类下的方法名称
    • 第三行:调用隐藏类下的hello方法获得的返回内容

    是不是还挺简单?

    如果你跟我一样平时会参与一些基础框架的开发工作的话,一定觉得这个功能还挺不错的吧!

    本文首发:Java 15 新特性:隐藏类
    本期视频:Java 15 新特性:隐藏类

    好了,今天的分享就到这里!如果您学习过程中如遇困难?可以加入我们超高质量的技术交流群,参与交流与讨论,更好的学习与进步!

    欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

  • 相关阅读:
    sql 查询
    射频问答精选 | 网络分析仪的问题汇总和解答
    机器学习-李宏毅-【1】机器学习的基本概念
    Python基础入门篇【22】--python中的函数:初时函数及函数的参数
    [ 数据结构进阶 - C++ ] 二叉搜索树
    Python使用EasyOCR库对行程码图片进行OCR文字识别介绍与实践
    论文解读(CGC)《CGC: Contrastive Graph Clustering for Community Detection and Tracking》
    Redis-数据类型-List
    uniapp 手机 真机测试 ​ 云打包 要是没申请 可以使用云打包 然后采用 测试权限即可​
    Spirngboot中文乱码解决方案
  • 原文地址:https://www.cnblogs.com/didispace/p/16286483.html