范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Java每半年更新一次新特性,再不掌握就要落伍了Java9的新特性

  从 2017 年开始,Java 版本更新策略从原来的每两年一个新版本,改为每六个月一个新版本,以快速验证新特性,推动 Java 的发展。从 《JVM Ecosystem Report 2021》 中可以看出,目前开发环境中有近半的环境使用 Java8,有近半的人转移到了 Java11,随着 Java17 的发布,相信比例会有所变化。
  因此,准备出一个系列,配合示例讲解,阐述各个版本的新特性。概述
  相较于 Java8,Java9 没有新增语法糖,但是其增加的特性也都是非常实用的,比如 Jigsaw 模块化、JShell、发布-订阅框架、GC 等。本文将快速、高层次的介绍一些新特性,完整的特性可以参加openjdk.java.net/projects/jd…
  这里需要说明一下,由于 Java9 并不是长期支持版,当前也是从现在看过去,所以笔者偷个懒,文章的示例代码都是在 Java11 下写的,可能会与 Java9 中的定义有些出入,不过,这也没啥,毕竟我们真正使用的时候还是优先考虑长期支持版。  Jigsaw 模块化
  模块化是一个比较大的更新,这让以前 All-in-One 的 Java 包拆分成几个模块。这种模块化系统提供了类似 OSGi 框架系统的功能,比如多个模块可以独立开发,按需引用、按需集成,最终组装成一个完整功能。
  模块具有依赖的概念,可以导出功能 API,可以隐藏实现细节。
  还有一个好处是可以实现 JVM 的按需使用,能够减小 Java 运行包的体积,让 JVM 在内存更小的设备上运行。JVM 当时的初衷就是做硬件,也算是不忘初心了。
  另外,JVM 中com.sun.*  的之类的内部 API,做了更强的封闭,不在允许调用,提升了内核安全。
  在使用的时候,我们需要在 java 代码的顶层目录中定义一个module-info.java  文件,用于描述模块信息:module cn.howardliu.java9.modules.car {     requires cn.howardliu.java9.modules.engines;     exports cn.howardliu.java9.modules.car.handling; } 复制代码
  上面描述的信息是:模块cn.howardliu.java9.modules.car  需要依赖模块cn.howardliu.java9.modules.engines  ,并导出模块cn.howardliu.java9.modules.car.handling  。
  更多的信息可以查看 OpenJDK 的指引 openjdk.java.net/projects/ji… Jigsaw 模块的使用,内容会贴到评论区。全新的 HTTP 客户端
  这是一个千呼万唤始出来的功能,终于有官方 API 可以替换老旧难用的HttpURLConnection  。只不过,在 Java9 中,新版 HTTP 客户端是放在孵化模块中(具体信息可以查看 openjdk.java.net/jeps/110)。
  老版 HTTP 客户端存在很多问题,大家开发的时候基本上都是使用第三方 HTTP 库,比如 Apache HttpClient、Netty、Jetty 等。
  新版 HTTP 客户端的目标很多,毕竟这么多珠玉在前,如果还是做成一坨,指定是要被笑死的。所以新版 HTTP 客户端列出了 16 个目标,包括简单易用、打印关键信息、WebSocket、HTTP/2、HTTPS/TLS、良好的性能、非阻塞 API 等等。
  我们先简单的瞅瞅:final String url = "https://postman-echo.com/get"; final HttpRequest request = HttpRequest.newBuilder()         .uri(new URI(url))         .GET()         .build();  final HttpResponse response = HttpClient.newHttpClient()         .send(request, HttpResponse.BodyHandlers.ofString());  final HttpHeaders headers = response.headers(); headers.map().forEach((k, v) -> System.out.println(k + ":" + v));  System.out.println(response.statusCode()); System.out.println(response.body()); 复制代码
  新版 HTTP 客户端可以在 Java11 中正常使用了,上面的代码也是在 Java11 中写的,API 是在  java.net.http  包中。改进的进程 API
  在 Java9 中提供的进程 API,可以控制和管理操作系统进程。也就是说,可以在代码中管理当前进程,甚至可以销毁当前进程。进程信息
  这个功能是由java.lang.ProcessHandle  提供的,我们来瞅瞅怎么用:final ProcessHandle self = ProcessHandle.current(); final long pid = self.pid(); System.out.println("PID: " + pid);  final ProcessHandle.Info procInfo = self.info();  procInfo.arguments().ifPresent(x -> {     for (String s : x) {         System.out.println(s);     } });  procInfo.commandLine().ifPresent(System.out::println); procInfo.startInstant().ifPresent(System.out::println); procInfo.totalCpuDuration().ifPresent(System.out::println); 复制代码
  java.lang.ProcessHandle.Info  中提供了丰富的进程信息销毁进程
  我们还可以使用java.lang.ProcessHandle#destroy  方法销毁进程,我们演示一下销毁子进程:ProcessHandle.current().children()         .forEach(procHandle -> {             System.out.println(procHandle.pid());             System.out.println(procHandle.destroy());         }); 复制代码
  从 Java8 之后,我们会发现 Java 提供的 API 使用了  Optional  、Stream  等功能,**Eating your own dog food **也是比较值得学习的。其他小改动
  Java9 中还对做了对已有功能做了点改动,我们来瞅瞅都有哪些。改进 try-with-resources
  从 Java7 开始,我们可以使用try-with-resources  语法自动关闭资源,所有实现了java.lang.AutoCloseable  接口,可以作为资源。但是这里会有一个限制,就是每个资源需要声明一个新变量。
  也就是这样:public static void tryWithResources() throws IOException {     try (FileInputStream in2 = new FileInputStream("./")) {         // do something     } } 复制代码
  对于这种直接使用的还算方便,但如果是需要经过一些列方法定义的呢?就得写成下面这个样子:final Reader inputString = new StringReader("www.howardliu.cn 看山"); final BufferedReader br = new BufferedReader(inputString); // 其他一些逻辑 try (BufferedReader br1 = br) {     System.out.println(br1.lines()); } 复制代码
  在 Java9 中,如果资源是final  定义的或者等同于final  变量,就不用声明新的变量名,可以直接在try-with-resources  中使用:final Reader inputString = new StringReader("www.howardliu.cn 看山"); final BufferedReader br = new BufferedReader(inputString); // 其他一些逻辑 try (br) {     System.out.println(br.lines()); } 复制代码改进钻石操作符 (Diamond Operator)
  钻石操作符(也就是<>  )是 Java7 引入的,可以简化泛型的书写,比如:Map> strsMap = new TreeMap>(); 复制代码
  右侧的TreeMap  类型可以根据左侧的泛型定义推断出来,借助钻石操作符可以简化为:Map> strsMap = new TreeMap<>(); 复制代码
  看山会简洁很多,<>  的写法就是钻石操作符 (Diamond Operator)。
  但是这种写法不适用于匿名内部类。比如有个抽象类:abstract static class Consumer {     private T content;      public Consumer(T content) {         this.content = content;     }      abstract void accept();      public T getContent() {         return content;     } } 复制代码
  在 Java9 之前,想要实现匿名内部类,就需要写成:final Consumer intConsumer = new Consumer(1) {     @Override     void accept() {         System.out.println(getContent());     } }; intConsumer.accept();  final Consumer<? extends Number> numConsumer = new Consumer(BigDecimal.TEN) {     @Override     void accept() {         System.out.println(getContent());     } }; numConsumer.accept();  final Consumer<?> objConsumer = new Consumer("看山") {     @Override     void accept() {         System.out.println(getContent());     } }; objConsumer.accept(); 复制代码
  在 Java9 之后就可以使用钻石操作符了:final Consumer intConsumer = new Consumer<>(1) {     @Override     void accept() {         System.out.println(getContent());     } }; intConsumer.accept();  final Consumer<? extends Number> numConsumer = new Consumer<>(BigDecimal.TEN) {     @Override     void accept() {         System.out.println(getContent());     } }; numConsumer.accept();  final Consumer<?> objConsumer = new Consumer<>("看山") {     @Override     void accept() {         System.out.println(getContent());     } }; objConsumer.accept(); 复制代码私有接口方法
  如果说钻石操作符是代码的简洁可读,那接口的私有方法就是比较实用的一个扩展了。
  在 Java8 之前,接口只能有常量和抽象方法,想要有具体的实现,就只能借助抽象类,但是 Java 是单继承,有很多场景会受到限制。
  在 Java8 之后,接口中可以定义默认方法和静态方法,提供了很多扩展。但这些方法都是public  方法,是完全对外暴露的。如果有一个方法,只想在接口中使用,不想将其暴露出来,就没有办法了。这个问题在 Java9 中得到了解决。我们可以使用private  修饰,限制其作用域。
  比如:public interface Metric {     // 常量     String NAME = "METRIC";      // 抽象方法     void info();      // 私有方法     private void append(String tag, String info) {         buildMetricInfo();         System.out.println(NAME + "[" + tag + "]:" + info);         clearMetricInfo();     }      // 默认方法     default void appendGlobal(String message) {         append("GLOBAL", message);     }      // 默认方法     default void appendDetail(String message) {         append("DETAIL", message);     }      // 私有静态方法     private static void buildMetricInfo() {         System.out.println("build base metric");     }      // 私有静态方法     private static void clearMetricInfo() {         System.out.println("clear base metric");     } } 复制代码JShell
  JShell 就是 Java 语言提供的 REPL(Read Eval Print Loop,交互式的编程环境)环境。在 Python、Node 之类的语言,很早就带有这种环境,可以很方便的执行 Java 语句,快速验证一些语法、功能等。$ jshell |  欢迎使用 JShell -- 版本 13.0.9 |  要大致了解该版本,请键入:/help intro  复制代码
  我们可以直接使用/help  查看命令jshell> /help |  键入 Java 语言表达式,语句或声明。 |  或者键入以下命令之一: |  /list [<名称或 id>|-all|-start] |   列出您键入的源 |  /edit <名称或 id>  。很多的内容,鉴于篇幅,先隐藏 复制代码
  我们看下一些简单的操作:jshell> "This is a test.".substring(5, 10); $2 ==> "is a "  jshell> 3+1 $3 ==> 4 复制代码
  也可以创建方法:jshell> int mulitiTen(int i) { return i*10;} |  已创建 方法 mulitiTen(int)  jshell> mulitiTen(3) $6 ==> 30 复制代码
  想要退出 JShell 直接输入:jshell> /exit |  再见 复制代码JCMD 新增子命令
  jcmd  是用于向本地 jvm 进程发送诊断命令,这个命令是从 JDK7 提供的命令行工具,常用于快速定位线上环境故障。
  在 JDK9 之后,提供了一些新的子命令,查看 JVM 中加载的所有类及其继承结构的列表。比如:$ jcmd 22922 VM.class_hierarchy -i -s java.net.Socket 22922: java.lang.Object/null |--java.net.Socket/null |  implements java.io.Closeable/null (declared intf) |  implements java.lang.AutoCloseable/null (inherited intf) |  |--sun.nio.ch.SocketAdaptor/null |  |  implements java.lang.AutoCloseable/null (inherited intf) |  |  implements java.io.Closeable/null (inherited intf) 复制代码
  第一个参数是进程 ID,都是针对这个进程执行诊断。我们还可以使用set_vmflag  参数在线修改 JVM 参数,这种操作无需重启 JVM 进程。
  有时候还需要查看当前进程的虚拟机参数选项和当前值:jcmd 22922 VM.flags -all  。多分辨率图像 API
  在 Java9 中定义了多分辨率图像 API,我们可以很容易的操作和展示不同分辨率的图像了。java.awt.image.MultiResolutionImage  将一组具有不同分辨率的图像封装到单个对象中。java.awt.Graphics  类根据当前显示 DPI 度量和任何应用的转换从多分辨率图像中获取变量。
  以下是多分辨率图像的主要操作方法:Image getResolutionVariant(double destImageWidth, double destImageHeight)  :获取特定分辨率的图像变体-表示一张已知分辨率单位为 DPI 的特定尺寸大小的逻辑图像,并且这张图像是最佳的变体。List getResolutionVariants()  :返回可读的分辨率的图像变体列表。
  我们来看下应用:final List images = List.of(         ImageIO.read(new URL("https://static.howardliu.cn/about/kanshanshuo_2.png")),         ImageIO.read(new URL("https://static.howardliu.cn/about/hellokanshan.png")),         ImageIO.read(new URL("https://static.howardliu.cn/about/evil%20coder.jpg")) );  // 读取所有图片 final MultiResolutionImage multiResolutionImage = new BaseMultiResolutionImage(images.toArray(new Image[0]));  // 获取图片的所有分辨率 final List variants = multiResolutionImage.getResolutionVariants();  System.out.println("Total number of images: " + variants.size());  for (Image img : variants) {     System.out.println(img); }  // 根据不同尺寸获取对应的图像分辨率 Image variant1 = multiResolutionImage.getResolutionVariant(100, 100); System.out.printf(" Image for destination[%d,%d]: [%d,%d]",         100, 100, variant1.getWidth(null), variant1.getHeight(null));  Image variant2 = multiResolutionImage.getResolutionVariant(200, 200); System.out.printf(" Image for destination[%d,%d]: [%d,%d]",         200, 200, variant2.getWidth(null), variant2.getHeight(null));  Image variant3 = multiResolutionImage.getResolutionVariant(300, 300); System.out.printf(" Image for destination[%d,%d]: [%d,%d]",         300, 300, variant3.getWidth(null), variant3.getHeight(null));  Image variant4 = multiResolutionImage.getResolutionVariant(400, 400); System.out.printf(" Image for destination[%d,%d]: [%d,%d]",         400, 400, variant4.getWidth(null), variant4.getHeight(null));  Image variant5 = multiResolutionImage.getResolutionVariant(500, 500); System.out.printf(" Image for destination[%d,%d]: [%d,%d]",         500, 500, variant5.getWidth(null), variant5.getHeight(null)); 复制代码变量句柄(Variable Handles)
  变量句柄(Variable Handles)的 API 主要是用来替代java.util.concurrent.atomic  包和sun.misc.Unsafe  类的部分功能,并且提供了一系列标准的内存屏障操作,用来更加细粒度的控制内存排序。一个变量句柄是一个变量(任何字段、数组元素、静态表里等)的类型引用,支持在不同访问模型下对这些类型变量的访问,包括简单的 read/write 访问,volatile 类型的 read/write 访问,和 CAS(compare-and-swap) 等。
  这部分内容涉及反射、内联、并发等内容,后续会单独介绍,文章最终会发布在 从小工到专家的 Java 进阶之旅 中,敬请关注。  发布-订阅框架
  在 Java9 中增加的java.util.concurrent.Flow  支持响应式 API 的发布-订阅框架,他们提供在 JVM 上运行的许多异步系统之间的互操作性。我们可以借助SubmissionPublisher  定制组件。
  关于响应式 API 的内容可以先查看 www.reactive-streams.org/的内容,后续单独介绍,… 从小工到专家的 Java 进阶之旅 中,敬请关注。怎么感觉给自己刨了这么多坑,得抓紧时间填坑了。  统一 JVM 日志记录
  在这个版本中,为 JVM 的所有组件引入了一个通用的日志系统。它提供了日志记录的基础。这个功能是通过-Xlog  启动参数指定,并且定义很多标签用来定义不同类型日志,比如:gc(垃圾收集)、compiler(编译)、threads(线程)等等。比如,我们定义debug  等级的 gc 日志,日志存储在gc.log  文件中:java -Xlog:gc=debug:file=gc.log:none 复制代码
  因为参数比较多,我们可以通过java -Xlog:help  查看具体定义参数。而且日志配置可以通过jcmd  命令动态修改,比如,我们将日志输出文件修改为gc_other.log  :jcmd ${PID} VM.log output=gc_other.log what=gc 复制代码新的 API不可变集合
  在 Java9 中增加的java.util.List.of()  、java.util.Set.of()  、java.util.Map.of()  系列方法,可以一行代码创建不可变集合。在 Java9 之前,我们想要初始化一个有指定值的集合,需要执行一堆add  或put  方法,或者依赖guava  框架。
  而且,这些集合对象是可变的,假设我们将值传入某个方法,我们就没有办法控制这些集合的值不会被修改。在 Java9 之后,我们可以借助ImmutableCollections  中的定义实现初始化一个不可变的、有初始值的集合了。如果对这些对象进行修改(新增元素、删除元素),就会抛出UnsupportedOperationException  异常。
  这里不得不提的是,Java 开发者们也是考虑了性能,针对不同数量的集合,提供了不同的实现类:List12  、Set12  、Map1  专门用于少量(List 和 Set 是 2 个,对于 Map 是 1 对)元素数量的场景ListN  、SetN  、MapN  用于数据量多(List 和 Set 是超过 2 个,对于 Map 是多余 1 对)的场景改进的 Optional 类
  Java9 中为Optional  添加了三个实用方法:stream  、ifPresentOrElse  、or  。
  stream  是将Optional  转为一个Stream  ,如果该Optional  中包含值,那么就返回包含这个值的Stream  ,否则返回Stream.empty()  。比如,我们有一个集合,需要过滤非空数据,在 Java9 之前,写法如下:final List> list = Arrays.asList(         Optional.empty(),         Optional.of("看山"),         Optional.empty(),         Optional.of("看山的小屋"));  final List filteredList = list.stream()         .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())         .collect(Collectors.toList()); 复制代码
  在 Java9 之后,我们可以借助stream  方法:final List filteredListJava9 = list.stream()         .flatMap(Optional::stream)         .collect(Collectors.toList()); 复制代码
  ifPresentOrElse  :如果一个Optional  包含值,则对其包含的值调用函数action  ,即action.accept(value)  ,这与ifPresent  方法一致;如果Optional  不包含值,那会调用emptyAction  ,即emptyAction.run()  。效果如下:Optional optional = Optional.of(1); optional.ifPresentOrElse(x -> System.out.println("Value: " + x), () -> System.out.println("Not Present."));  optional = Optional.empty(); optional.ifPresentOrElse(x -> System.out.println("Value: " + x), () -> System.out.println("Not Present."));  // 输出结果为: // 作者:看山 // 佚名 复制代码
  or  :如果值存在,返回Optional  指定的值,否则返回一个预设的值。效果如下:Optional optional1 = Optional.of("看山"); Supplier> supplierString = () -> Optional.of("佚名"); optional1 = optional1.or(supplierString); optional1.ifPresent(x -> System.out.println("作者:" + x));  optional1 = Optional.empty(); optional1 = optional1.or(supplierString); optional1.ifPresent(x -> System.out.println("作者:" + x));  // 输出结果为: // 作者:看山 // 作者:佚名 复制代码文末总结
  本文介绍了 Java9 新增的特性,完整的特性清单可以从openjdk.java.net/projects/jd… Java8 到 Java17 的新特性系列完成后补充, 青山不改,绿水长流,我们下次见。
  原文链接:https://juejin.cn/post/7061389685699903525
金融app开发怎么做银弹谷金融app开发怎么做?做之前我们先了解一下我们做金融APP的背景,随着我国经济快速发展,人均收入不断增加的同时,银行利息已经逐渐不能满足人们的期望收益,人们开始思考如何提高闲钱的收银弹谷什么是可视化编程工具什么是可视化编程工具?顾名思义就是将代码可视化操作,百度百科是这样说的可视化编程,亦即可视化程序设计以所见即所得的编程思想为原则,力图实现编程工作的可视化,即随时可以看到结果,程序制作APP的软件哪个好用制作APP的软件哪个好用?有什么推荐吗?对于传统的制作APP的软件来说,无非就是安装环境,然后逐个逐个的敲代码,稍微智能一点的就是可以识别首字母自动弹出相应的代码序列,但是这类软件Linux远程管理工具(PuTTY和SecureCRT)通过Linux远程管理协议一节中可以知道,Linux远程管理服务器多基于SSH协议。下面给大家介绍2种常见的基于SSH协议的远程管理工具,分别是PuTTY和SecureCRT。在使Linux安装Linux系统对硬件有什么要求?很多初学者在安装Linux系统时,都对自己的电脑配置存在质疑,担心其是否能够满足安装Linux的要求。本节就从CPU内存硬盘显卡等这些方面,详细介绍一下安装Linux系统的最低配置Linux简介开源协议是什么?有哪些?如何选择?开源软件在追求自由的同时,不能牺牲程序员的利益,否则将会影响程序员的创造激情,因此世界上现在有60多种被开源促进组织(OpenSourceInitiative)认可的开源许可协议来Linux文件系统的层次结构通过前面的学习我们知道,Linux一切皆文件,平时打交道的都是文件,那么,应该如何找到它们呢?很简单,在Linux操作系统中,所有的文件和目录都被组织成以一个根节点开始的倒置的树状雨夜边城本应下雪的时候却下起了雨10月的最后一天,作为边城黑河来说已入初冬,往年的这个时候都已经下过雪了,但今年不但雪没下来,傍晚,天空竟然飘起了雨丝,稀里哗啦的下的还不小。傍晚下雨,如果夜里降温,早上就会是一场边城黑河已成了太平鸟这些吃货的乐园太平鸟来到黑河已经一个月了。它们在小区公园和大黑河岛上流连忘返,在花楸棠梨丛中往来穿梭。它们驻留在中俄边境这座小城的目的只有一个,那就是吃吃吃。由于黑河市区大量的花楸等浆果的存在,边城又见太平鸟十月末的边城黑河,又见到太平鸟了。太平鸟,名字很好听,看小鸟也挺漂亮的。太平鸟这个季节来到黑河市区是有原因的,因为最近这些年黑河市内的公园小区里栽种了大量的花楸树,而原来在黑河就有坝上金秋,五彩东北第一天,奈曼旗沙漠骆驼冲沙说在前面还是九月初,家乡黑河影友风雨同舟在网上转发了一则摄影团出行的信息,是哈尔滨影友云端组织的摄影团,主要行程是坝上,辽宁本溪以及长白山下红叶等景点。看了行程,有点心动。退休后有
掘金千亿级安防市场,LED小间距屏持续发力近年来,随着5GAI技术迅速发展,安防系统也更加智能化。超高清LED显示屏作为安防领域不可或缺的重要显示媒介,其作用也越来越重要。随着安防领域海康威视大华科达等企业进入LED显示领如果说深圳是赚钱之都,那惠州一定是机遇之地,看未来深圳这座一线大都市,造就了很多富豪!这是小编对于深圳,最直接的理解评论。早期来到深圳的人,可以遇见遍地机遇,就算是摆个小地摊,那都可能在几年后,身价变成百万富翁。做生意在深圳可行,中融信托信托业半年数据显示,业绩增长,转型压力仍在2021年已过半,信托业包括市场公司业绩等各类半年数据基本公布完毕。数据显示,受近年来宏观经济下行压力增大新冠疫情政策调控等多重因素影响,上半年集合信托市场,以及各信托公司信托业绩抖音西瓜快手,有哪些闪光点?看完这篇秒懂抖音创作者大会正在进行,部分草根一族能跟明星同台,同样有着闪光的焦点,这是抖音创作者自己拼搏奋斗得来的,更是抖音这个短视频平台赐予的机遇。小编就综合讲一讲抖音西瓜和快手,这三个短视带货主播收入如何?取决于主播的能力!超越实体店绰绰有余这篇文章就谈点敏感的问题,大家都经常刷短视频平台,或者是刷直播平台,都能看见好多主播,像是疯了一样似的在视频带货。究竟主播们这样的疯疯癫癫带货,到底有多少月收入?或者是年收入多少呢为什么会有人呢自私的基因14章读书笔记自私的基因这本书的读书笔记有点长,摘抄和想法加起来有3万字。为了方便阅读,把笔记按章节顺序分了五个部分14章为第一部分,主要讲从复制子到生存机器的进化。510章为第二部分,主要讲生做小生意名列第一,再到参与抖音转型,浙江人这么有料?每个人都想发财致富,但是同样的机遇,都摆在了大家面前,却还是有些人错过了!这里就不得不说一下浙江人,真是太会赚钱了。难道是浙江人天生就很聪明吗?小编可以明确的告诉你,这个世界上就没关于轻创业的文章,草根一族最好时代!真的是时势造英雄中国发生了两件大事第一件大事是以数字经济为核心的新发展模式诞生,正在推动新经济体加速增长。第二件大事是国家实施的共同富裕战略布局,即将推动劳动人民,实现走向富裕阶层。左看右看不论怎SEM想赢,就多得1分知乎给推荐了1个问题网站一天发多少文章有利于SEO优化?不用打开网页,也知道会看到些什么答案固定数量的按规律更新的强调质量更重要的这些答案让人觉得很好笑,也很可悲。好笑的是,一个简国内外互联网大厂,都进军元宇宙布局,是豪赌还是机遇呢?近期,关于元宇宙话题,蹭蹭直上成为了热点,国内外互联网大厂,都在布局未来的发展之路。到底是对赌元宇宙项目,还是提前布局未来市场呢?关于这个深层次的问题。每家互联网大厂的理解不同,那iQOONeo5入手一天后的使用体验iQOONeo5个人认为还是挺不错的,当初在S9和iQOONeo之间因为外观问题难以抉择实际入手后,外观和官网的商品详情图一致,手感也行,至少我是这么认为的赠品也不少,这个价格还算