文链接:http://justinblank.com/experiments/howmanytypeparameterscanajavamethodhave.html

在 JVM 中,一个 Java 方法,最多能定义多少参数呢?这是一个很无聊的问题,即使能定义一万个,十万个,谁又会真的去这么做呢。

但是作为一个 coder,最重要的不就是好奇心吗,没有好奇心,和一条咸鱼又有什么区别呢?本文作者就是这样一位充满好奇心的 coder。

我最近给我的 QuickTheories 分支添加了一个接口:

@FunctionalInterface
public interface QuadFunction<A, B, C, D, E> {E apply(A a, B b, C c, D d);
}

让我好奇的是这个方法能有多少个类型参数。到目前为止,我敢说,Java 语言规范并没有谈及这个问题。

对于实现定义的限制可能是什么,我有两个猜测:

  1. 编译器会设置一个可预测的限制,如 255 或 65535。

  2. 编译器的紧急行为会由于实现细节(堆栈溢出或同样不可预测/不相关的东西)而设置意外的限制。

我不想在源代码上测试我那点可怜的 C++技巧,所以我决定只测试编译器做了什么。我写了一个 Python 脚本,它使用二进制搜索找到最少的致错类型参数。完整的脚本放在 Github repo (https://github.com/hyperpape/java-max-type-params) 中。

脚本地址:https://github.com/hyperpape/java-max-type-params

生成方法很简单。幸运的是,我们不必使用任何类型参数,只需以<a,b,c…>的形式发出它们:

def write_type_plain(count):with open('Test.java', 'w') as f:f.write("public class Test {\n")f.write("public <")for i in range(count):if (i > 0):f.write(", ")f.write("A" + str(i + 1))f.write("> void testMethod() {}")f.write("}")

运行二进制搜索可以得到以下输出:

>>> error: UTF8 representation for string "<A1:Ljava/lang/Objec..." is too long for the constant pool
>>> largest type: 2776

这个错误有点模糊,但事后看来是可以预见的。编译器生成的类文件包含许多字符串,包括类中每个方法的方法签名。这些字符串存储在常量池中,常量池中的条目最大为 65535 字节,这是由 JVM 规范规定的限制。

所以,我之前的猜测都不完全正确。类型参数的最大数目是一个突现特征(emergent property),而不是一个明确的决定。不过,并不是编译器本身的实现导致了错误。

相反,JVM 的类文件格式限制了可以在类文件中表示的类型参数的数量。这是真的,尽管 JVM对泛型一无所知。这也意味着类型参数的最大数目完全取决于如何编写方法。

我尝试了一种新的编码类型参数的方法(先前链接文件中的 write_Type_Compact),使用完整的合法 ASCII 字符(A-Z、a-z、$和_)。该实现有点过于复杂,因为可以使用字符 0~9,但不能是标识符的初始字符,因为 Java 关键字不能作为类型参数出现。我只是用等长的 UTF-8 字符替换了短单词「if」和「do」。更紧凑的编码将参数数量从 2776 增加到 3123。

不方便的是,_A 是一种合法的 Java 标识符,但 _ 不是。谢天谢地,我的编码在不使用初始_情况下就生成了 3392 个 2 字节类型参数,因此我觉得没有必要进行簿记以发出初始字符_。

再来一个小技巧

解压类文件显示,65536 个字符的大部分不是我生成的类型参数,而是子字符串 Ljava/lang/object 的重复实例。因为没有提供关于类型参数的信息,所以类文件显示它们扩展了对象,并在方法签名中对其进行编码。我修改了生成器来解决这个问题。

循环的关键部分是:

s = type_var(i)
f.write(s)
if (s != 'A'):f.write(" extends A")

在类型参数中,除了一个实例 java/Lang/Object 之外的所有实例都被替换为 A。在进行了这个更改之后,编译了一个具有 9851 个类型参数的方法。

由于参数的数量增加了很多,所以我使用的代码肯定需要调整。使用非 ASCII Unicode 标识符可能是完全高效的必要条件,但简单地指出这是可以做到的我就很满意了。

这些都不重要

很难想象有人会达到这个极限。代码生成有时会达到语言或编译器的限制,但即使生成的代码似乎也不太可能使用成百上千的类型参数。

尽管如此,如果我是规则制定者,我会考虑明确禁止任何类或方法具有 255 个以上的类型参数。明确的限制似乎更好,即使它只影响百万分之一的程序。

关微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的教程,都是干货。

猜你喜欢

1、GitHub 标星 3.2w!史上最全技术人员面试手册!FackBoo发起和总结

2、如何才能成为优秀的架构师?

3、从零开始搭建创业公司后台技术栈

4、程序员一般可以从什么平台接私活?

5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6、滴滴业务中台构建实践,首次曝光

7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

8、15张图看懂瞎忙和高效的区别

9、2T架构师学习资料干货分享

一个 Java 方法,最多能定义多少参数?相关推荐

  1. java定义一个空数组_一个 Java 方法,最多能定义多少参数?

    点击上方"JAVA",星标公众号重磅干货,第一时间送达 文链接:http://justinblank.com/experiments/howmanytypeparametersca ...

  2. 一个Java方法能有多少个参数类型?这个好奇coder做了个实验

    在 JVM 中,一个 Java 方法,最多能定义多少参数呢?这是一个很无聊的问题,即使能定义一万个,十万个,谁又会真的去这么做呢.但是作为一个 coder,最重要的不就是好奇心吗,没有好奇心,和一条咸 ...

  3. 420一个像素多少个字节_一个Java方法能有多少个参数类型?这个好奇coder做了个实验...

    在 JVM 中,一个 Java 方法,最多能定义多少参数呢?这是一个很无聊的问题,即使能定义一万个,十万个,谁又会真的去这么做呢.但是作为一个 coder,最重要的不就是好奇心吗,没有好奇心,和一条咸 ...

  4. java方法参数类型不确定_一个Java方法能有多少个参数类型?这个好奇coder做了个实验...

    选自 justinblank 机器之心编译 参与:李志伟.张倩 在 JVM 中,一个 Java 方法,最多能定义多少参数呢?这是一个很无聊的问题,即使能定义一万个,十万个,谁又会真的去这么做呢.但是作 ...

  5. Java方法签名的定义

    In Java, a method signature is part of the method declaration. It's the combination of the method na ...

  6. 如何在jsp中写一个java方法

    一般用<%!  %>在jsp中写java方法 代码如下: <%@ page language="java" import="java.util.*,ja ...

  7. java web项目初始化启动一个java方法

    项目中需要一些初始化数据,或者加载中断的任务. 首先在web.xml中配置信息,配置在<web-app>中: <servlet><servlet-name>Init ...

  8. java中不允许一个方法在自身定义的内部调用自己_Java面向对象三大特性(基础篇)...

    面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA). 面向对象设计(OOD).面向对象程序设计(OOP)等新的系统开发方式模型的研究. 对语言 ...

  9. Java方法中的参数太多,第7部分:可变状态

    在我的系列文章的第七篇中,有关解决Java方法或构造函数中过多参数的问题 ,我着眼于使用状态来减少传递参数的需要. 我等到本系列的第七篇文章来解决这个问题的原因之一是,它是我最不喜欢的减少传递给方法和 ...

  10. java值传递和引用传递_辨析Java方法参数中的值传递和引用传递

    小方法大门道 小瓜瓜作为一个Java初学者,今天跟我说她想通过一个Java方法,将外部变量通过参数传递到方法中去,进行逻辑处理,方法执行完毕之后,再对修改过的变量进行判断处理,代码如下所示. publ ...

最新文章

  1. structs2文件下载
  2. 故事工程学:人工智能和程序化叙事生成
  3. 数据科学的5种基本的面向业务的批判性思维技能
  4. 7000 字,四年多 Java 的 BAT 面经分享!
  5. java hashcode 例子_Java UUID hashCode()用法及代码示例
  6. 类的初始化列表_【Flutter 111】Flutter手把手教程Dart语言——类、类的的成员变量和方法、类的构造函数...
  7. 值此中秋圆月夜 数据天涯共此时
  8. 手动标记用例状态_【自动化接口用例】从 1 到 1000 过程中的实践和思考
  9. Fiddler使用和数据抓包
  10. 物联网工程毕业设计简介
  11. 本地事务、分布式事务以及解决方案
  12. [隐匿的学习笔记]JVM(2)运行时数据区
  13. android fsck,android fsck_msdos分析(一)
  14. Word2019 插入脚注问题
  15. CodeVS 1359 数字计数 51nod 1042 数字0-9的数量 Pascal
  16. 网页瘦身方法-金瑞帆高端建站
  17. 笔记本屏幕给另一台当扩展屏幕_chenjie的博客
  18. TRY HACK ME | INTERNAL「渗透测试挑战02」
  19. 网站商务通使用总结:
  20. mendeley中如何重复引用同一篇参考文献_科研小白如何高效阅读下载的文献/论文,怎么样做笔记?给大家安利几种工具和方法!赶快收藏起来...

热门文章

  1. Java学习笔记——dubbo服务之底层通讯协议Protocol
  2. zookeeper中ExpiryQueue详解
  3. Android kotlin中配置protobuf
  4. Electron —— Cannot find module ‘jquery.min.js’(II)
  5. React Native : AsyncStorage 存储
  6. CRM中复制记录的方法
  7. 存储网络性能岂能只靠“猜”
  8. DOM 的一些知识记载
  9. SQL2008系统统计函数
  10. php5 相关软件下载