Java 缺失的特性:扩展方法

2023-01-26
阅读 8 分钟
1.8k
扩展方法,就是能够向现有类型直接“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改现有类型。调用扩展方法的时候,与调用在类型中实际定义的方法相比没有明显的差异。

@CrossOrigin 支持正则表达式

2019-12-28
阅读 8 分钟
6.7k
最近有个应用被检测发现有个缺陷,使用 @CrossOrigin 的地方用的都是默认选项(即 origins="*")—— 允许任何网站进行跨域访问。为了避免可能存在的安全隐患,师兄说 “之叶,你把这个问题解决一下,只允许部分网站的跨域”。

Log4j 结合钉钉打造日志机器人

2019-10-20
阅读 12 分钟
5.6k
在平常的开发中,找问题时,看日志经常是不可或缺的一件事件。对于错误日志,我们更是希望能够立马悉知,迅速对错误追本溯源,然后对错误进行修正。钉钉机器人的出现,无疑为我们第一时间对错误日志进行响应,提供了绝妙的工具。

Java8(7):自制多糖 switch

2019-10-05
阅读 12 分钟
7.2k
新特性很美好,但是如今在业界最流行的版本依然是 JDK8,所以想要在生产环境用上这么舒服的 switch,目前看来还是遥遥无期。好在我们还有 Lambda,正所谓 “自己动手,丰衣足食”,我们来试试能不能自己做出一个和 JDK12 & JDK13 的 swtich 类似的东西,给我们平淡的编码生活,加点糖。

基于 AOP 抽离方法的重复代码

2019-09-01
阅读 24 分钟
4.7k
今天师兄和我说,“之叶,你设计一个方案,把目前业务方法中和业务无关的逻辑都抽离出来,让每个方法只关心自己的业务逻辑”。我会心一笑 👇(因为我们早应该做这件事情了)

MyBatis Generator 自定义生成注释

2018-09-26
阅读 10 分钟
30.8k
最近做项目,ORM 使用的是 MyBatis,为了偷懒,我自然而然的想到了使用 MyBatis Generator(MBG)来生成数据库表对应的实体代码和 Mapper 代码。于是做了如下的配置(对 MBG 配置不熟悉的同学可以参考 Mybatis Generator最完整配置详解):

Java 应用:自制高精度计算器(2)

2017-08-29
阅读 8 分钟
3.8k
上一篇 文章讲了如何通过正则来将输入的表达式解析为多个 Token,而这篇文章的核心在于如何对 表达式求值。我们输入的表达式,即我们通常见到的表达式,都是中缀表达式 —— 中缀的含义是,在表达式中,运算符是放中间的,比如 (1 + 2) * 3,运算符都是在数的中间。然而在计算机的世界里,还存在着前缀表达式和后缀表达式 ...

Java 应用:自制高精度计算器(1)

2017-08-29
阅读 9 分钟
4.7k
一直以来,我的计算器都是 Python 的 REPL(Java8 之后偶尔也用 jjs (Nashorn))。但是这些 REPL 的问题在于,在涉及到小数时,它们使用的是浮点数进行运算,于是不可避免的出现了浮点数精度缺失的问题:

Java 多线程(7): ThreadLocal 的应用及原理

2017-07-19
阅读 8 分钟
7.3k
在涉及到多线程需要共享变量的时候,一般有两种方法:其一就是使用互斥锁,使得在每个时刻只能有一个线程访问该变量,好处就是便于编码(直接使用 synchronized 关键字进行同步访问),缺点在于这增加了线程间的竞争,降低了效率;其二就是使用本文要讲的 ThreadLocal。如果说 synchronized 是以“时间换空间”,那么 Thre...

Java8(6):使用并行流

2017-03-31
阅读 7 分钟
6.4k
对于斐波那契数的计算,我们都知道最容易理解的就是递归的方法: {代码...} 当然这个递归也可以转化为迭代: {代码...} 但是,对于以上两种方法,并不能并行化,因为后一项的值依赖于前一项,使得算法流程是串行的。所以引出了可以并行的计算斐波那契数的公式: => f0 和 f1 都是 1 —— 很明显我们可以对 进行并行计算...

Java8(5):使用 Optional 处理 null

2017-03-14
阅读 7 分钟
40k
但是很多时候,我们可能会忘记写 if (user != null) —— 如果在开发阶段就发现那还好,但是如果在开发阶段没有测试到问题,等到上线却出了 NullPointerException ... 画面太美,我不敢继续想下去。

Java 多线程(6):volatile 关键字的使用

2017-03-10
阅读 4 分钟
4.6k
volatile 作为 Java 语言的一个关键字,被看作是轻量级的 synchronized(锁)。虽然 volatile 只具有synchronized 的部分功能,但是一般使用 volatile 会比使用 synchronized 更有效率。在编写多线程程序的时候,volatile 修饰的变量能够:

Java 多线程(5):Fork/Join 型线程池与 Work-Stealing 算法

2017-01-17
阅读 5 分钟
15.9k
JDK 1.7 时,标准类库添加了 ForkJoinPool,作为对 Fork/Join 型线程池的实现。Fork 在英文中有 分叉 的意思,而 Join 有 合并 的意思。ForkJoinPool 的功能也是如此:Fork 将大任务分叉为多个小任务,然后让小任务执行,Join 是获得小任务的结果,然后进行合并,将合并的结果作为大任务的结果 —— 并且这会是一个递归的...

Java多线程(4):使用线程池执行定时任务

2017-01-07
阅读 4 分钟
51.5k
在现实世界里,我们总是免不了要定期去做一件事情(比如上课)—— 在计算机的世界里,更是如此。比如我们手机每天叫我们起床的电子闹钟,某些网站会定期向我们发送一些推荐相关的邮件,集群中我们需要每隔一定时间检查是否有机器宕机等。

Java多线程(3):取消正在运行的任务

2016-12-29
阅读 7 分钟
31.7k
当一个任务正在运行的过程中,而我们却发现这个任务已经没有必要继续运行了,那么我们便产生了取消任务的需要。比如 上一篇文章 提到的线程池的 invokeAny 方法,它可以在线程池中运行一组任务,当其中任何一个任务完成时,invokeAny 方法便会停止阻塞并返回,同时也会 取消其他任务。那我们如何取消一个正在运行的任务?

Java多线程(2):使用线程池 ThreadPoolExecutor

2016-12-26
阅读 11 分钟
17.9k
首先,我们为什么需要线程池?让我们先来了解下什么是 对象池 技术。某些对象(比如线程,数据库连接等),它们创建的代价是非常大的 —— 相比于一般对象,它们创建消耗的时间和内存都很大(而且这些对象销毁的代价比一般对象也大)。所以,如果我们维护一个 池,每次使用完这些对象之后,并不销毁它,而是将其放入池中,...

Java8(4):当 forEach 需要索引

2016-12-21
阅读 3 分钟
41.6k
在 上一篇文章 中,我们讨论了如何使用 Java8 中 Map 添加的新方法 computeIfAbsent 来统计集合中每个元素出现的所有位置,代码如下:

Java8(3):Java8 中 Map 接口的新方法

2016-12-18
阅读 7 分钟
14.4k
比如,给定 list:["a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g"] ,那么应该返回:a : [0]b : [1, 2]c : [3, 4, 5]d : [6, 7, 8]f : [9, 10]g : [11]

Java8(2):Java8 对字符串连接的改进

2016-12-17
阅读 4 分钟
16.9k
JDK1.8 时,添加了一个新的用于字符串连接的类,专门用于这种需要 分隔符 的场合,它就是 StringJoiner。StringJoiner 在构造时可以指定一个分隔符(delimiter),然后每连接一个元素它便会加上一个 delimiter,使用 StringJoiner 改写 formatList:

Java8(1):当 Lambda 遇上受检异常

2016-12-17
阅读 6 分钟
20.3k
Files.walk(Path) 在 JDK1.8 时添加,深度优先遍历一个 Path (目录),返回这个目录下所有的 Path(目录和文件),通过 Stream<Path> 返回;

Java 多线程(1):获得线程的返回结果

2016-12-12
阅读 7 分钟
20.1k
Java 对多线程编程提供了内置的支持并提供了良好的 API,通过使用 Thread 和 Runnable 两个基础类,我们可以很方便的创建一个线程:

Java网络编程(3):使用 UDP 探测局域网内特定类型的机器

2016-12-08
阅读 9 分钟
5.9k
记得以前我们使用类似“快牙”这些文件分享工具的时候,一开始就是先在 手机A 上创建一个“房间”,然后连接上 手机A WiFi 热点的其他手机(即这些手机处于一个局域网内)就可以发现到这个房间并加入到这个房间里面,然后就可以互相分享文件了。那没有建立连接的情况下,“发现房间”这个功能是怎么实现的呢?首先,既然 手机A...

Java 网络编程(2):UDP 的使用

2016-11-25
阅读 5 分钟
5.2k
今天的主角是 UDP(User Datagram Protocol,用户数据报协议)。我们都知道 TCP 是一种可靠的协议 —— 首先客户端和服务端需要建立连接(三次“握手”),数据发送完毕需要断开连接(四次“挥手”);如果发送数据时数据损坏或者丢失,那么 TCP 会重新发送。保证可靠的代价就是效率的降低(建立连接和断开连接就需要时间,保...

Java 网络编程(1):使用 NetworkInterface 获得本机在局域网内的 IP 地址

2016-11-12
阅读 3 分钟
31.4k
在使用 Java 开发网络程序时,有时候我们需要知道本机在局域网中的 IP 地址。很常见的一种做法是调用本地命令(比如 Windows 上的 ipconfig 命令和 Linux 上的 ifconfig 命令),接着解析本地命令的输出,最后得到本机在局域网内的 IP 地址。很明显,这种做法不够方便,也不够 Java。于是引出了 Java 在 JDK1.4 的时候添...