Java

以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类。record关键词的引入,主要是为了提供一种更为简洁、紧凑的final类的定义方式。 下面就来具体了解record类的细节。 声明record类声明record类的基础语法: record range(int start, int end){} 我们知道class类可以在单独文件中生命,也可以在其他类中申明。那么record类也一样,它有这几种申明方式: 单独文件申明: public record range(int start, int end){} 在类内部申明: public class DidispaceTest { public record range(int start, int end)...

隐藏类,是一种不能被其他类直接使用的类。引入隐藏类的主要目的是给框架来使用,使得框架可以在运行时生成类,并通过反射间接使用它们。可能有点抽象,不要紧,下面我们通过一个例子来直观的认识它! 隐藏类案例第一步:先创建一个普通的Java类 public class JEP371HiddenClasses { public static String hello() { return "https://www.didispace.com"; }} 第二步:编译一下,或得编译后的class文件。然后使用Base64对文件内容Encode,你可以用各种工具,也可以用下面代码来获取: String filePath = "JEP371HiddenClasses.class";byte[] b = Files.readAllBytes...

还记得Java 16中的instanceof增强吗? 通过下面这个例子再回忆一下: Map<String, Object> data = new HashMap<>();data.put("key1", "aaa");data.put("key2", 111);if (data.get("key1") instanceof String s) { log.info(s);} 上面这个场景里,Map中的Value值存在不同的类型,所以使用instanceof来判断取出的value是什么类型,然后根据不同类型来进行处理。那么,接下来继续思考一个问题,如果这个Map中的Value可能有这几种类型:String、Integer、Double,我们需要对不同类型分别做不同的处理,是不是处理结构要这样写: if (data.get("key") in...

面对这样的if语句,你是不是很难受呢? if (flag == 1) { log.info("didispace.com: 1");} else if (flag == 2) { log.info("didispace.com: 2");} else if (flag == 3) { log.info("didispace.com: 3");} else if (flag == 4) { log.info("didispace.com: 4");} else { log.info("didispace.com: x");} 是不是想到用switch来改进一下? switch(flag) { case 1: log.info("didispace.com: ...

Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360、JDK 16中的JEP 397),最终定稿于JDK 17中的JEP 409。Sealed Classes有两种主流翻译:密封类、封闭类。个人喜欢前者多一些,所以在本文中都称为密封类。其实Sealed Classes的其他许多语言中并不是什么新鲜事物,C#、Scala等高级语言中都有类似的名称,但意义和作用各不相同。下面就来一起认识一下Java 17中的Sealed Classes。 密封类的作用在面向对象语言中,我们可以通过继承(extend)来实现类的能力复用、扩展与增强。但有的时候,有些能力我们不希望被继承了去做一些不可预知的扩展。所以,我们需要对继承关系有一些限制的控制手段。而密封类的作用就是限制类的继承。 已有的限制手段对于继承能力的控制,Java很早就已经有一...

instanceof这个关键词,主要用来判断某个对象是不是某个类的实例。 比如,有时候我们要处理一个类似这样的数据集: Map<String, Object> data = new HashMap<>();data.put("key1", "aaa");data.put("key2", 111); 这个Map中的Value值因为可能是不同的对象,所以定义的是Object。这个时候,当我们get出来的时候,就需要去判断和转换之后再去处理。 比如,我们取出key1的value,然后截取一段字符串的操作,就需要这样写: Object value =data.get("key1");if (value instanceof String) { String s = (String) value; System.out.println(s.substri...

假设有这样一个场景,我们需要做一个工具。用来自动生成项目文档,文档可以通过浏览器查看,所以最后产出物肯定是一堆html文件。为了让这些html文件更容易读,良好的格式肯定要保持,该换行的换行、该缩进的缩进。 那么,在组织最后内容的时候,你可能就会这样子来写: String html = "<html>\n" + "<body>\n"+ " <h1>Java 15 新特性:文本块 | 程序猿DD</h1>\n"+ " <p>didispace.com</p>\n"+ "</body>\n"+ "</html>\n"; 当然,也许你也会改进一下,用StringBuilder或者StringBuffer来优化,但不论用什么来写,都逃不了一些要转义的内容...

近日,New Relic发布了最新的2022 Java生态系统报告,这份报告可以帮助我们深入的了解Java体系的最新使用情况,下面就一起来看看2022年,Java发展的怎么样了,还是Java 8 YYDS吗? Java 11成为新的标准在2020年的时候,Java 11已经推出了1年多,但当时Java 8的占有率高达84.48%。2年过去了,Java 11上生产的比例第一次超过Java 8,占有率已经达到了48.44%。曾今的霸主Java 8几乎跌掉了一半,以46.45%占据第二。 而大势所趋的、整个Java生态都在拥抱的Java 17在排行榜上还是处于比较低的位置。这个其实还是意料之中的,因为生态的支持还需要一定时间的演进,比如Spring这个Java生态的大基座,对于Java 17的重要支持还要等到今年年底的Spring Boot 3发布(对这部分感兴趣的小伙伴记得关注我,公...

在这次的Java 18中,新增了一个@snipppet标签,主要用于JavaDoc中需要放示例代码的场景。其实在Java 18之前,已经有一个@code标签,可以用于在JavaDoc中编写小段的代码内容,比如在之前介绍Simple Web Server视频中,提到的这段样例代码,就是用@code标签来写的: * <p> Example of a simple file server:* <pre>{@code* var addr = new InetSocketAddress(8080);* var server = SimpleFileServer.createFileServer(addr, Path.of("/some/path"), OutputLevel.INFO);* server.start();* }<...

本期视频:https://www.bilibili.com/video/BV1YY4y1a7vG 在Java 18中,将UTF-8指定为标准Java API的默认字符集。有了这一更改,依赖于默认字符集的API将在所有实现、操作系统、区域设置和配置中保持一致。 做这一更改的主要目标: 当Java程序的代码依赖于默认字符集时,使其更具可预测性和可移植性。 阐明标准Java API在哪里使用默认字符集。 在整个标准Java API中对UTF-8进行标准化,但控制台I/O除外。 需要注意的是,这一更改的目标并不是定义新的标准Java API或受支持的JDK API,尽管这项工作可能会发现新的便利方法可能会使现有的API更易于使用,这一更改并不是要弃用或删除依赖默认字符集的标准Java API。 动机用于读写文件和处理文本的标准Java API允许将字符集作为参数传递。字符集控制Java编...

昨天分享了Java 18 新特性:简单Web服务器的jwebserver命令行功能。今天换一种方式,使用Java代码来实现一个静态资源服务器。 详细步骤我录了个视频放到B站了,感兴趣的小伙伴可以点击查看Java 18 新特性:Simple Web Server(2) 代码比较简单,直接贴出来了: public class Main { public static void main(String[] args) { System.out.println("Hello world!"); var addr = new InetSocketAddress(9000); var server = SimpleFileServer.createFileServer( addr, Path.of(...

在今年3月下旬的时候,Java已经更新到了18。接下来会挑一些有意思的内容,以文章和视频的方式来给大家介绍和学习。 如果要第一时间获得内容更新,对文章形式感兴趣的小伙伴可以关注我的博客或者公众号(程序猿DD),对视频形式感兴趣的可以关注我的B站或视频号(程序猿DD)。 本篇内容对应视频已完成录制,点击查看:Java 18 新特性:Simple Web Server(1) 简单Web服务器:jwebserverJEP 408: Simple Web Server,是这次Java 18推出的一个比较独立的全新功能点。我们可以通过命令行工具来启动一个提供静态资源访问的迷你Web服务器。 该工具的定位官方文档中说了一堆: 这里我简单总结几点,方便大家理解: 构建目的是应用于测试与教学,不是为了替代Jetty、Nginx等高级服务器 不提供身份验证、访问控制或加密等安全功能 仅支持HTTP...

最新消息!根据Log4j官网发布,2.17.0版本还存在漏洞! 上图来自Log4j2官网:https://logging.apache.org/log4j/2.x/ 漏洞编号:CVE-2021-44832 漏洞内容:Log4j2提供的JDBCAppender功能,将日志信息写入数据库中,这个过程需要JNDI的支持,故攻击者可以利用此来执行任意代码。 危害等级:中 影响范围:2.17.0及以下版本(不包含2.12.4、2.3.2) 修复措施:升级Log4j2的版本 Java 8或之后用户升级到最新的2.17.1 Java 7用户升级到2.12.4 Java 6用户升级到2.3.2 这个漏洞跟之前曝出的Logback漏洞类似,因为存在苛刻的利用条件,所以危害并不是很大。也许后面你马上会看到很多来自营销号危言耸天的标题,希望你可以冷静看待,不必慌张… 点赞,转发,让更多人知道本质,不...

本以为,经过上周的2.16.0版本升级,Log4j2的漏洞修复工作,大家基本都要告一段落了。 万万没想到,就在周末,Log4j官方又发布了新版本:2.17.0 该版本主要修复安全漏洞:CVE-2021-45105 影响版本:2.0-alpha1 至 2.16.0(1.x用户继续忽略) 该漏洞只有当日志配置使用带有Context Lookups的非默认 Pattern Layout(例如$${ctx:loginId})时,攻击者可以通过构造包含递归查找的恶意输入数据,触发无限循环,导致 StackOverflowError,最终进程崩溃。 这次漏洞受影响的只有log4j-core,仅使用log4j-api的程序不需要担心。所以,大家可以通过升级log4j-core来修复该漏洞的 <dependency> <groupId>org.apache.logg...

昨天,Apache Log4j 团队再次发布了新版本:2.16.0! 2.16.0 更新内容 默认禁用JNDI的访问,用户需要通过配置log4j2.enableJndi参数开启 默认允许协议限制为:java、ldap、ldaps,并将ldap协议限制为仅可访问Java原始对象 Message Lookups被完全移除,加固漏洞的防御 更多细节,可以通过官网查看:https://logging.apache.org/log4j/2.x/ 如果您正在学习Spring Boot,那么推荐一个连载多年还在继续更新的免费教程:https://blog.didispace.com/spring-boot-learning-2x/ Spring Boot用户如何升级Spring Boot用户依然可以通过前几天分享的Spring Boot应用简易升级Spring Boot下所有log4j版本的...