【问题标题】:How to fix "The code of method .. is exceeding the 65535 bytes limit"?如何解决“方法的代码..超过 65535 字节限制”?
【发布时间】:2012-08-28 18:05:38
【问题描述】:

我有以下代码:

public static void main(String[] args) {
    try {
        String[] studentnames = {
            /* this is an array of 9000 strings... */
        };
    }
}

尝试编译时出现以下错误:

The code of method main(String[]) is exceeding the 65535 bytes limit

【问题讨论】:

  • The amount of code per non-native, non-abstract method is limited to 65536 bytes by the sizes of the indices in the exception_table of the Code attribute (§4.7.3), in the LineNumberTable attribute (§4.7.8), and in the LocalVariableTable attribute (§4.7.9). 根据java文档docs.oracle.com/javase/specs/#88659
  • 是 9000 还是 90,000 ?

标签: java compiler-errors


【解决方案1】:

你的方法太长了。

创建不同的方法来拆分它,使其更具可读性和可维护性。

【讨论】:

    【解决方案2】:

    错误代码似乎不言自明。

    The code of method main(String[]) is exceeding the 65535 bytes limit 
    

    这是因为在 Java 中,对于方法大小存在 64Kb 的任意硬编码限制。 (实际上很多其他的东西都限制在 64K 以内,例如方法名称、常量的数量等。有关详细信息,请参阅 Java 8 specsJava 7 specs。)

    要解决这个问题,您只需将 main(String[] args) 方法分解为多个子方法即可。


    但是为什么不直接从文件中加载名称呢?

    按照您目前建议的方式进行操作的一些问题是:

    • 首先,你在硬编码细节,这几乎总是一件坏事(见this);

    • 其次,您会收到该错误消息;和

    • 第三,你的代码很难阅读。

    当然还有更多,但这些是显而易见的。

    【讨论】:

    • 为什么要从文件加载?我所做的只是拥有一个数组并打印该数组?我从文件中读取没有问题,但想知道我们为什么要这样做......我真的不知道数组是什么
    • 有几个问题:首先,你在硬编码细节,这几乎总是一件坏事;其次,您会收到该错误消息;第三,你使你的代码非常不可读。当然还有更多,但这些是显而易见的。
    【解决方案3】:

    在 java 中,方法不能超过 65535 个字节。

    因此,要解决此问题,请将您的 main(String[] args) 方法分解为多个子方法。

    【讨论】:

      【解决方案4】:

      初始化 studentnames 数组将计入 main 方法的大小。由于有 9000 个学生姓名,每个姓名只能包含大约 7 个字符,否则空间不足。正如其他人所说,您需要减小方法的大小。正如 Pramod 所说,您可以将其拆分为多个部分,但在这种情况下,该方法的大部分实际上是数据。我会按照 Infiltrator 的说法将名称拆分到一个单独的文件中,然后在您的主文件中读取它。像 commons-io 这样的东西可以用来让你有效地到达你开始的位置。

      List<String> namelist = FileUtils.readLines(new File("studentnames.txt"));
      String[] studentnames = namelist.toArray(new String[0]);
      

      您可能会发现处理列表而不是将其转换为数组很有用,或者您可以使用 LineIterator 代替

      LineIterator it = FileUtils.lineIterator(file);
      try {
           while (it.hasNext()) {
               String line = it.nextLine();
               // do something with line
           }
       } finally {
           it.close();
       }
      

      【讨论】:

        【解决方案5】:

        我会从一个文件中读取学生的名字,但是有一种方法可以让班级变小

        String[] studentnames= "Student names is an array of :9000".split(" ");
        

        这里只使用一个,而不是定义和使用 9000 个字符串。单个 String 的上限刚刚超过 20 亿。

        【讨论】:

        • 这会产生同样的错误:The code for the static initializer is exceeding the 65535 bytes limit
        • @minipif 你能解释为什么那是因为它不适合我。字符串不在代码块中,因此不会影响代码块大小。
        • 我试图创建一个包含前 100000 个以空格分隔的素数的字符串,该字符串的长度为 710485。我声明它有 private static final,但收到错误 The type generates a string that requires more than 65535 bytes to encode in Utf8 format in the constant pool。看来您不能拥有长度超过 65535 的字符串文字(源代码中嵌入的字符串常量)。因此,在这种情况下,必须从文件中读取它。
        • @minipif 正确,但这是一个不同的错误。如果您创建一个大约 4000 字节的数组,您将收到代码块大小错误。使用字符串,您可以获得 65535 个字节。
        【解决方案6】:

        方法 main(String[]) 的代码超过了 65535 字节的限制

        正如您的错误所说,主要方法超出了 65535 字节的限制。

        原因:为什么我们的代码中出现此错误?

        • 我们知道数组的内存分配将按顺序完成。 IE;如果 RAM 中连续有如此大量的可用空间,则会为数组分配内存。
        • 我们使用了包含一些“9000”字符串的字符串数组——这些字符串太大而无法保存在内存中
        • 在这段时间里,RAM 可能不会连续有这么大的空间,所以我们可能遇到了这个错误。

        解决方案:那我该怎么办?

        • 为了存储如此巨大的大小值,我们可能更喜欢文件进行读/写 - 因此我们可以在需要时读取文件的一部分
        • 我们可以将这些字符串存储在 ArrayList 中,当元素添加到其中时,它会增加内存,而不是最初分配整个内存。

        【讨论】:

          【解决方案7】:

          只需将代码中的字符串外部化为一个 *.properties / xml / json 文件。 Netbeans 和/或 Eclipse 可以轻松为您完成。

          【讨论】:

            【解决方案8】:

            解决方案 1:

            public static void main(String[] args) {
                int[] num ={100001,100002,.......,...};
            }
            

            假设数组 num 包含 100000 个数字,而您的 main 函数会出错。在这种情况下,您可以将上述数组分成两部分。现在,您可以声明 2 个不同的数组,而不仅仅是一个数组。例如:

            static int[] num1 ={}static int[] num2={}

            在主函数外声明num1,在主函数内声明num2,num2 将替换主函数内的num

            数组num的所有元素将被拆分成两个子数组num1num2;以这样一种方式拆分,即静态和非静态数组都可以容纳 8000 和 2000 个元素。

            main 方法中的代码可以处理所有 10000 个元素,只是一个假设:

            if (n <= 8000) {
                System.out.println(" --->  " + num2[((int) n - 1)]);
            } else if (n > 8000 && n <= 10000) {
                n = n - 8000;
                System.out.println(" --->  " + num1[((int) n - 1)]);
            }
            

            因此,拆分该数组或将元素分成 8000 和 2000 两部分,可以消除错误。

            解决方案 2

            将数组放在 main 方法之外,num1num2 现在都是静态数组,但 65535 字节的限制也适用于静态初始化数组。拆分您的元素,例如,您可以将 10000 拆分为 8000 和 2000,或者根据您的要求拆分为 main 方法之外的两个静态数组。

            此错误与 long[]int[] 中的元素存储有关,如果存储大小超过 65535 的限制,则会发生错误。在这种情况下,请拆分元素,例如,如果您使用 @ 987654340@ 或 int[] 将它们拆分为合适的数字,直到错误得到解决。

            换句话说,不强制只将数组拆分为 2 部分,您也可以将它们分成 4 种不同的大小或不同的相等部分。但同样,您的问题的解决方案可能会根据您的要求而有所不同。

            【讨论】:

            • 将上述场景中的数组 num 分成 2 个不同的数组,例如 int[] num ={};将变为 int[] num ={} 和 int[] num1={};并将您的元素分配到这些不同数组中的 2 个部分中。
            • 您可以edit 您的答案并在其中包含评论中的那部分。请阅读how to improve your answer - 有点混乱
            猜你喜欢
            • 1970-01-01
            • 2020-08-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-02-15
            • 2023-03-24
            相关资源
            最近更新 更多