千家信息网

一个Java方法可以使用多少个参数

发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,这篇文章主要介绍"一个Java方法可以使用多少个参数",在日常操作中,相信很多人在一个Java方法可以使用多少个参数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"一个J
千家信息网最后更新 2024年11月17日一个Java方法可以使用多少个参数

这篇文章主要介绍"一个Java方法可以使用多少个参数",在日常操作中,相信很多人在一个Java方法可以使用多少个参数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"一个Java方法可以使用多少个参数"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

我最近给我fork的项目QuickTheories增加了一个接口:

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

这让非常好奇一个方法能够有多少个类型参数呢?据我所知,Java的语言规范并没有提到这个问题。1

关于在实现上这个阈值的定义,我有两个猜测:

编译器会强制一个可预测的阈值,例如255或者65535。

由于实现细节的原因,编译器的异常处理会施加意想不到的限制。

我不想通过我薄弱的C++技能来测试源代码,所以我决定直接来测试编译器2。我写了一个Python脚本,通过二分法找到一个会触发错误的最小值。完整的代码请见连接Github Repo。

最直接的办法就是生成方法。幸运的是,我们不必使用任何已有的类型参数,只需要按照

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 ">> largest type: 2776

这个错误让人有点费解,但是从事后来看还是可以理解的。编译器生成的类文件包含多个字符串,包括每个方法的方法签名。这些字符串保存在常量池内,而常量池的内容有最大65535字节数的限制,这个是JVM的所定义的。

所以,我之前的猜测都不是完全的正确。类型参数的最大个数是一个意料之外的值,而不是一个确定值。但是,编译器的实现本身并不是导致错误的原因3。相反,是JVM类文件的格式要求限制了类型参数可使用的数量。其实JVM对泛型本身一无所知。

这同时也表示类型参数的最大个数取决于你写的方法代码4。我尝试用另外一种类型参数的编码方案(先前链接文中的write_type_compact),使用全部合法的ASCII字符。这个实现是有点繁琐的,因为字符0-9是合法的,但不能作为标识符的首字母,并且Java关键字也不能作为类型参数。我仅仅将if和do替换为等长的UTF-8字符。采用这种更紧凑的编码方案让类型参数的个数从2776提升到了3123。

还是有一些不太方便的地方,例如_A是一个合法的Java标识符,但是_不是。我的编码在不使用_作为首字幕的情况下,最高生成了3392个2字节的类型参数。所以我觉得不用考虑_作为首字母的情况了。

另外一个技巧

通过反编译类文件,我观察到65536个字符中大部分都不是我生成的类型参数,而是重复的字符串Ljava/lang/Object;。这是因为类型参数没有包含额外的信息,所以类文件将其视为Object的继承,并将它们编入方法签名内。我通过修改我的生成器来优化这个问题。

循环的关键代码修改为:

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

除开一个实例之外,所有的类型参数都从继承java/lang/Object改为继承A。这个修改将类型参数的数量提升到9851个。

类型参数的数量提升了非常多,而我所使用的编码方法还可以继续改进。例如使用非ASCII unicode标识符,不过我已经比较满意现在的效果了。

这些都不重要

在实际情况中是不太可能达到上述数量限制的。代码生成时可能会达到语言或者编译器的某些极限,就算罕见的遇到了生成上百个类型参数的情况,那距离几千个的限制仍然还相距很远。

尽管如此,如果我是规则的制定者,我将不允许任何类或者方法使用超过255个类型参数的情况。即使只影响了百万分之一的程序,有明确的限制会更好。

  1. §4.4, §8.1.2, §9.1.2, §8.4.4, §8.8.4 这些章节都和方法或者类的类型参数有关,但是都没有指明允许有多少个类型参数。

  2. 当我写这段话时,我想起了Hotspot是C++写的,javac是Java写的。就算这样我依然会选择做代码实验,而不是阅读代码。阅读别人代码是种煎熬

  3. 逗号之后的空格不会影响,因为编译器会规范化它的输出。

  4. 这也表示与我使用哪个JVM无关。为了完整性,我在Fedora 29上使用了1.8.0_191-b13版本的OpenJdk。

到此,关于"一个Java方法可以使用多少个参数"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

参数 类型 方法 代码 编译 字符 编译器 生成 限制 情况 数量 文件 编码 学习 合法 最大 个数 字符串 标识 标识符 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全b区调剂 r星服务器创建账号失败 网络安全知识内容 小学生 工业网络技术是文科还是理科 攻城掠地数据库以资源修改器 适合软件开发人员的笔记本 美国标准数据库 安卓创建一个数据库跟表 为什么服务器贵吗 河西区信息网络技术不二之选 闵行区工商软件开发哪家便宜 兰州学习网络安全费用多少 数据库对以后软件开发的重要性 网络技术的就业前景和就业方向 临沂鑫康网络技术支持 万网数据库主机填什么 中国的6g网络技术 网络技术及应用实例 日本樱花云服务器网址 游戏软件开发学什么专业好 藏宝阁怎么取消服务器选择 奉贤区推广软件开发排名靠前 功能安全和网络安全区别 网络安全防火墙相关知识 数据库中的查询功能是 数据库远程查询条数时多时少 青岛便捷式设备管理软件开发 中国网络安全法简读 海天味业的数据库 盘古网络技术公司大会
0