Java 平台历代特性
Created|Updated|Java
|Word Count:16|Reading Time:1mins|Post Views:
Java 9 模块化,JDK 只依赖于 PATH 不依赖于 CLASSPATH。
Author: magicliang
Link: https://magicliang.github.io/2020/03/01/Java-%E5%B9%B3%E5%8F%B0%E5%8E%86%E4%BB%A3%E7%89%B9%E6%80%A7/
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-05-21
下推自动机:多一只栈就能处理嵌套
DFA 和 NFA 都只有有限状态。状态数量再多,也仍然是有限的。它们适合识别固定模式、分支和重复,但面对任意深度的嵌套结构时会遇到硬边界。 括号匹配就是最小例子。()、(())、(()()) 都合法,(()、())、)( 都非法。有限状态机可以识别“最多三层括号”“最多十层括号”,但只要深度没有上限,有限状态就不够用了。机器需要一种能随输入增长的记忆结构。 下推自动机(Pushdown Automaton,PDA)给有限状态机加了一只栈。状态仍然有限,但栈可以随着输入增长。读到左括号就压栈,读到右括号就弹栈;输入结束后,栈如果回到底部符号,括号就匹配完成。 栈解决的是后进先出问题 括号嵌套天然是后进先出结构。最近打开的左括号,必须最先被右括号关闭。 123456789(()())1234561: push (2: push (3: pop (4: push (5: pop (6: pop ( 第 2 个字符打开的括号,要在第 3 个字符关闭;第 4 个字符打开的括号,要在第 5 个字符关闭;第 1 个字符打开的括号最后关闭。这个顺序正好是栈。 有限状态机无法保存任意多个...

2022-05-09
Lombok 拾遗
sneakyThrow 12345678public static RuntimeException sneakyThrow(Throwable t) { if (t == null) throw new NullPointerException("t"); return Lombok.<RuntimeException>sneakyThrow0(t); } private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T { throw (T)t; }
2019-09-05
重述双亲委派模型
何时加载类 根据 Java 语言规范(JLS §12.4),类或接口在首次主动使用时才会被初始化。主动使用包括以下情况: 遇到 new、getstatic、putstatic、invokestatic 等字节码指令时。这些指令分别对应创建对象实例、读取或设置静态字段、调用静态方法。 对类进行反射调用时,如 Class.forName() 或 Method.invoke()。 初始化某个类的子类时,父类会先被初始化(但父类接口不会)。 虚拟机启动时会先加载设置的主类,即包含 main() 方法的类。 使用 java.lang.invoke 包的动态语言支持特性时,如 MethodHandle 调用。 需要注意的是,被动引用(如通过数组引用、常量引用、访问子类的静态字段等)不会触发类初始化。 从 Java 到 cpp 源码分析 双亲委派模型的工作流程 双亲委派模型的核心逻辑在 java.lang.ClassLoader.loadClass(String name, boolean resolve) 方法中: 123456789101112131415161718192021222...
2026-05-21
抽象解释:用保守近似理解程序
停机问题说明,对任意程序做完备且正确的停机判断是不可能的。工程分析工具并没有因此失去意义。它们换了目标:不追求精确理解所有程序,而是用可计算的抽象信息给出有用结论。 抽象解释就是这个方向的代表。它把具体值集合映射到抽象域里,用保守规则模拟程序执行。只要抽象规则覆盖了所有可能的具体行为,分析结果就可以用于告警、优化或拒绝高风险程序。 本文用区间分析做一个最小模型:变量不再保存单个整数,而是保存可能取值范围。 从具体值到抽象值 具体执行关心单个值: 123x = 3y = 5z = x + y = 8 抽象执行关心值的集合。若只知道 x 在 0 到 10 之间,y 等于 5,就可以推出: 123x in [0, 10]y in [5, 5]z = x + y => z in [5, 15] 这个结果不精确。z 不一定等于区间里的每个数,但所有可能结果都被包含在 [5, 15] 里。保守性比精确性更重要:不能漏掉可能发生的值。 区间抽象域 区间可以用两个端点表示。 12345678910111213141516from dataclasses import dataclass@...

2026-01-12
Java 并发编程笔记
本文思维导图总览: 下载思维导图源文件 写在前面的话 并发编程最早的实践都在操作系统里。高层语言的并发模型都要基于底层系统对硬件抽象和并发的设计来设计和实现,不能超出操作系统允许的范围。所谓的高级抽象总体上是简化对 OS 底层机制的复杂调用。 并发与异步 本文聚焦并发(Concurrency),即多任务在同一时间段内的交替或并行执行,核心问题是资源共享、线程同步与协作。 **异步(Asynchronous)**是另一维度:调用方发起操作后不等结果返回即继续执行,通过回调、Future或事件机制获取结果。异步可通过单线程事件循环实现,也可依托多线程并发实现。 二者关系:并发关注"多任务如何执行与协调",异步关注"调用是否阻塞等待"。并发编程常涉及异步,但本文不展开异步编程模式(如响应式流、协程),相关内容请参阅《Java 线程池笔记》。 管程 理论和实践之间是有鸿沟的,要弥合这种鸿沟,通常需要我们去学习别人的实践。比如并发的标准设计思想来自于操作系统里的管程(monitor),我们应当学习管程,进而了解标准的并发模型-管理共享变量和线程(并...
2026-05-20
小步语义:把程序执行拆成一步一步的规约
上一篇写了大步语义。大步语义像一次函数调用:给它程序和环境,它直接返回最终环境。小步语义换了观察角度:程序运行时会经历一串中间配置,每一步只做一个局部变化。 这个视角很适合 Java 程序员理解调试器、解释器、状态机和工作流引擎。断点、单步执行、重试、恢复、超时保护,都依赖“当前程序状态可以被保存,下一步可以被明确计算”。 本文继续使用上一篇的小语言,补上小步语义(small-step semantics)。核心目标很直接:把一个完整程序改写成一台可推进的机器。 程序状态变成机器配置 小步语义关心的是配置之间的变化。 1(statement, environment) -> (next_statement, next_environment) statement 是剩余要执行的程序,environment 是当前变量绑定。每执行一步,语句可能变小,环境也可能变化。 例如: 12(x = 1 + 2, {}) -> (x = 3, {})(x = 3, {}) -> (do-nothing, &...





