【问题标题】:"Code too large" compilation error in JavaJava中的“代码太大”编译错误
【发布时间】:2011-01-25 08:39:19
【问题描述】:

Java 中的代码有最大大小吗?我写了一个超过 10,000 行的函数。实际上,每一行都为数组变量赋值。

arts_bag[10792]="newyorkartworld";
arts_bag[10793]="leningradschool";
arts_bag[10794]="mailart";
arts_bag[10795]="artspan";
arts_bag[10796]="watercolor";
arts_bag[10797]="sculptures";
arts_bag[10798]="stonesculpture"; 

在编译时,我得到这个错误:代码太大

我该如何克服这个问题?

【问题讨论】:

  • 我只是惊呆了......肯定会有更好的方法来做到这一点。
  • 你真的需要查看数据库来寻找这种类型的东西,而不是属性文件。
  • 你们为什么对这个可怜的家伙大喊大叫?也许 OP 通过一些代码生成工具获得了这种疯狂的方法。
  • 我惊呆了,这些肤浅的批评 cmet 得到了如此多的支持!
  • 当您可以让编译器在编译时预先生成所有内容时,为什么您的应用程序启动会花费大量时间来解析一些文本文件?如果您想在不重新编译的情况下更改数据,或者手动编写方法,这是一个糟糕的设计,但如果您生成源代码,这根本不是一个糟糕的设计。 (至少如果您以一种实际上允许编译器预生成数组的方式进行操作)。

标签: java arrays compiler-errors code-size


【解决方案1】:

这似乎有点疯狂。您不能通过从文本文件或其他数据源读取值来初始化数组吗?

【讨论】:

  • (投反对票,因为)这至少需要一个为什么这种技术不好的原因。想出一个好的理由并不容易。
【解决方案2】:

Java 类中的单个方法最多可以有 64KB 的字节码。

但你应该把它清理干净!

使用.properties文件存储这些数据,并通过java.util.Properties加载

您可以通过将.properties 文件放在您的类路径中来做到这一点,并使用:

Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);

【讨论】:

  • “不管你的 JDK/JVM 的实际大小是多少”?您是否暗示此限制不固定?因为它是固定的,并且是类文件格式规范所要求的。
  • 在哪里可以找到 .properties 文件
  • 你自己创建然后放到类路径中
  • 我没有使用你的建议,虽然我很想下次尝试一下。现在已经使用数据库来存储这些信息,并相应地修改了其余代码。
  • 如果这是一个愚蠢的问题,我很抱歉,但是.. 这个 .properties 文件应该放在哪里?我的意思是,好的,它在类路径中,但它在哪里?
【解决方案3】:

method 有 64K 字节码大小限制

话虽如此,我必须同意理查德的意见;为什么需要这么大的方法?鉴于 OP 中的示例,属性文件就足够了……如果需要,甚至可以使用数据库。

【讨论】:

  • 枚举呢?我对大量枚举遇到同样的问题
  • @Toby:我自己从来没有遇到过枚举的这个问题。不过,这里有其他用户关于相同问题的帖子。例如 - stackoverflow.com/questions/2546470 可能值得查看生成的 .class 文件以查看 enum 以查看
  • 枚举实例(即表示常量的对象)是在类的静态初始化器中创建的,它是一种方法,具有相同的限制。
  • 我在为一个非常复杂的 Web 表单生成框架代码时遇到了同样的问题。解决方案是将表单拆分为组件,因此每个组件的生成代码也被拆分。
【解决方案4】:

尝试重构您的代码。 Java中方法的大小是有限制的。

【讨论】:

  • 如果他在该方法中所做的只是数组初始化,那么重构并不是一个合理的想法。
  • 他说他的其余代码依赖于这是一个数组。所以他可以重构方法,将加载数据的责任从文件/数据库传递给其他方法/工厂。
  • 您可以创建和初始化大型数组,而无需诉诸这种废话;请参阅@Kris 的回答。
  • 重构 - “在不修改其外部功能行为的情况下更改计算机程序的源代码以改进软件的某些非功能属性的过程。”其他答案与此有何不同?
【解决方案5】:

正如其他答案中提到的,方法的字节码限制为 64KB(至少在 Sun 的 java 编译器中)

对我来说,将该方法分解为更多方法会更有意义 - 每个方法都将某些相关的东西分配给数组(使用 ArrayList 来执行此操作可能更有意义)

例如:

public void addArrayItems()
{
  addSculptureItems(list);
  ...
}

public void addSculptureItems(ArrayList list)
{
  list.add("sculptures");
  list.add("stonesculpture");
}

或者,如果它们像从属性文件中一样固定,您可以从静态资源加载项目

【讨论】:

  • 正确的答案是把数据当作数据,把代码当作代码。
  • @Malcolm 好吧,这显然是数据,而不是代码。您的评论具有误导性,因为您不应该做的是混合数据和代码,但在这里它们没有混合。
  • 我认为这是一个很好的解决方法。我遇到了这个问题,大约有 21k 行代码,其中包含 7000 条路由消息。我通过 div 将这些路由消息修复为名为 xxx0 的 7 个函数xxx1 xxx2.
【解决方案6】:

根据Java Virtual Machine specificationthe code of a method must not be bigger than 65536 bytes

code_length 项的值给出了此方法的 code 数组中的字节数。

code_length 的值必须大于零(因为代码数组不能为空)且小于 65536。

code_length 定义了包含方法实际字节码的code[] 属性的大小:

code 数组给出了实现该方法的 Java 虚拟机代码的实际字节数。

【讨论】:

  • 这不仅仅是方法大小的问题。如果将数组设为静态类成员,它也会失败。
  • @ACV:这是因为数组成员实际上是在合成代码中逐项初始化的,该合成代码放入静态初始化程序块中,最终形成一个代码块,并且也被视为一种方法。跨度>
  • 那是很好的洞察力。谢谢。我不知道这一点,但也看字节码,它不是很明显。我想javap 中标记为Code: 的任何块都是这些方法之一?
  • @AVC:Code: 部分只是各种方法和初始化程序的字节码(例如,静态初始化程序被标记为 static {};)。所以它既包含“正常”的方法代码,也包含编译器生成的合成代码,没有明显区别。
【解决方案7】:

我自己也遇到过这个问题。对我有用的解决方案是将方法重构并缩小为更易于管理的部分。和你一样,我正在处理一个将近 10K 行的方法。然而,通过使用静态变量以及更小的模块化函数,问题得到了解决。

似乎会有更好的解决方法,但是使用 Java 8,没有...

【讨论】:

    【解决方案8】:

    您可以添加另一种方法来为您的代码创建空间以获得额外的数据空间,您可能有一个占用大量数据空间的方法。尝试划分您的方法,因为我有同样的问题,并通过在我的 java Android 代码中为相同数据创建另一个附加方法来解决它,在我这样做之后问题就消失了。

    【讨论】:

    • 这更像是一个评论而不是一个答案。
    【解决方案9】:

    此错误有时是由于单个函数中的代码过大... 要解决该错误,请将该函数拆分为多个函数,例如

    //Too large code function
    private void mySingleFunction(){
    .
    .
    2000 lines of code
    }
    //To solve the problem
    private void mySingleFunction_1(){
    .
    .
    500 lines of code
    }
    private void mySingleFunction_2(){
    .
    .
    500 lines of code
    }
    private void mySingleFunction_3(){
    .
    .
    500 lines of code
    }
    private void mySingleFunction_4(){
    .
    .
    500 lines of code
    }
    private void MySingleFunction(){
    mySingleFunction_1();
    mySingleFunction_2();
    mySingleFunction_3();
    mySingleFunction_4();
    }
    

    【讨论】:

      【解决方案10】:

      我有一个导致 .java 文件大小超过 500KB 的枚举。 Eclipse 可以出于某种原因构建它; eclipse 导出的 ant build.xml 不能。我正在调查此问题并将更新此帖子。

      【讨论】:

        【解决方案11】:

        由于方法有大小限制,而此时您不想重新设计代码,您可以将数组拆分为 4-5 部分,然后将它们放入不同的方法中。在读取数组的时候,依次调用所有的方法。你也可以维护一个计数器来知道你已经解析了多少索引。

        【讨论】:

          【解决方案12】:

          这是由于单个方法中的所有代码 解决方法:创建更多一些小方法然后这个错误就会消失

          【讨论】:

            【解决方案13】:

            好吧,也许这个答案为时已晚,但我认为这种方式比另一种方式更好

            例如,我们在代码中有 1000 行数据

            1. 打破它们

              private void rows500() {
                   //you shoud write 1-500 rows here
              }
              
              private void rows1000() {
                   you shoud write 500-1000 rows here
              }
              
            2. 为了获得更好的性能,请在您的代码中添加“如果”

              if (count < 500) {
                  rows500();
              } else if (count > 500) {
                  rows1000();
              }
              

            希望这段代码对你有帮助

            【讨论】:

              【解决方案14】:

              我来这个问题是因为我试图解决一个类似的问题。出于性能原因,我想将具有 1600 个元素的图形硬编码到二维整数数组中。我在一个 leetcode 风格的网站上解决了一个问题,从文件中加载图形数据不是一个选项。整个图表超过了 64K 的最大值,所以我无法进行一次静态分配。我将分配分配给几个静态方法,每个方法都低于限制,然后一个一个地调用每个方法。

              private static int[][] G = new int[1601][];
              
              static {
                  assignFirst250();
                  assignSecond250();
                  assignSecond500();
                  assignThird500();
              }
              
              private static void assignFirst250() {
                  G[1] = new int[]{3,8,15,24,35,48,63,80,99,120,143,168,195,224,255,288,323,360,399,440,483,528,575,624,675,728,783,840,899,960,1023,1088,1155,1224,1295,1368,1443,1520,1599};
                  G[2] = new int[]{2,7,14,23,34,47,62,79,98,119,142,167,194,223,254,287,322,359,398,439,482,527,574,623,674,727,782,839,898,959,1022,1087,1154,1223,1294,1367,1442,1519,1598};
              

              【讨论】:

                猜你喜欢
                • 2016-03-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-03-28
                • 1970-01-01
                相关资源
                最近更新 更多