findconstructor用于高效获取构造函数方法句柄,仅准备调用能力而不执行构造;findspecial则精准定位指定类声明的方法,模拟invokespecial指令,支持super调用与private方法访问。

findConstructor:构造函数的高效句柄获取
findConstructor用于生成调用指定类构造函数的方法句柄,本质是把 new 操作抽象为可复用、可组合的调用单元。它不执行构造逻辑,只准备调用能力。
关键点在于参数匹配必须严格:传入的 MethodType 中,返回类型必须是 void.class,参数类型顺序和个数需与目标构造函数完全一致。例如 ArrayList(Collection) 构造器对应 MethodType.methodType(void.class, Collection.class)。
- 构造器及其所有参数类型,对 Lookup 对象必须可见(如 public 或同包/内部可访问)
- 若构造器声明了 varargs(如 String...),返回的 MethodHandle 自动具备 variable-arity 行为,调用时可传入任意数量对应参数
- 首次调用该 MethodHandle 会触发目标类的初始化(类加载、静态块执行),这点与 new 表达式行为一致
findSpecial:绕过动态分派的精准方法定位
findSpecial 不是“找父类方法”的快捷方式,而是以精确调用语义锁定某个类中声明的方法——无论该方法是否被子类重写。它模拟 invokespecial 字节码指令的行为,常用于实现 super 调用或绕过虚方法表查找。
它的第四个参数 specialCaller 是权限边界标识,不是目标类也不是调用者类,而是用于确定“从哪一层开始向上查”。JVM 会从 specialCaller 的直接父类开始,逐级向上搜索,直到 refc 类或找到匹配方法。这意味着:即使 refc 是子类,只要 specialCaller 是其父类,就能安全调用父类中定义的非重写方法。
- 不能用于调用 static 方法或接口默认方法
- 对 private 方法有效,但前提是 specialCaller 与 refc 在同一类或嵌套关系中,满足 Java 访问控制规则
- bindTo() 后再 invokeExact,才能确保 this 引用被正确传入,否则抛 IllegalArgumentException
两者共性:Lookup 是权限锚点
无论是 findConstructor 还是 findSpecial,都依赖 Lookup 实例的创建上下文。Lookup 对象在构造时就绑定了“lookup class”(通常是调用 lookup() 的那个类),所有 findXXX 操作的访问检查都基于这个类的权限视角。
- publicLookup() 返回的 Lookup 权限最宽,但仅能访问 public 成员
- 普通 lookup() 返回的 Lookup 可访问本类私有成员,但无法跨类访问其他类的 private 内容
- MethodHandle 本身无运行时权限校验,安全边界全在创建阶段锁定
选型建议:什么时候用哪个
需要实例化对象且追求比反射更稳定性能时,优先用 findConstructor。它语义明确、不易出错,适合构建通用对象工厂或序列化框架中的实例重建逻辑。
需要在子类中显式调用父类版本的方法(尤其当该方法被重写)、或实现类似 super.xxx() 的机制时,必须用 findSpecial。它不依赖运行时类型,也不受 override 影响,是实现精确方法绑定的核心工具。
两者都不替代反射,而是提供更底层、更可控、更接近 JVM 原语的调用能力。用对场景,才能真正发挥 MethodHandle 的性能与表达力优势。










