Java中的“代码太大”编译错误


94

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"; 

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

我该如何克服?


9
我被惊呆了……一定会有更好的方法来做到这一点。
Thanos Papathanasiou 2010年

6
您确实需要查看数据库来查找这种类型的内容,而无法找到该属性文件。
保罗·惠兰

44
你们为什么为糟糕的设计大喊大叫可怜的人?也许OP是通过某种代码生成工具获得了这种疯狂的方法。
webuster 2014年

14
我很惊讶这些肤浅的批评评论获得了如此多的赞誉!
Evgeni Sergeev

7
当您可以让编译器在编译时预生成所有内容时,为什么应用程序启动会花很多时间通过解析一些文本文件来完成?如果您要更改数据而无需重新编译或手动编写方法,那么这将是一个糟糕的设计,但是,如果您生成源代码,那根本不是一个糟糕的设计。(至少如果您这样做的方式实际上允许编译器预生成数组)。
Guntram Blohm

Answers:


92

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

但是您应该清理一下!

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

您可以通过将.properties文件放在类路径上并使用以下方法来执行此操作:

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

2
“无论您的JDK / JVM的实际大小是多少”?您是在暗示此限制不是固定的吗?因为它是类文件格式规范中固定的和必需的。
Joachim Sauer 2010年

1
我在哪里可以找到.properties文件
Trinity 2010年

1
您创建自己的内容,然后将其放在类路径中
马克2010年

3
我没有使用你的建议,但是我渴望下一次尝试它..现在已经使用了一个数据库来存储这些信息,并且“已经修改了代码的..其余据此
三位一体

1
如果这是一个愚蠢的问题,我很抱歉,但是..properties文件应该放在哪里?我的意思是,好的,它在类路径中,但是它在哪里?
Milack27年

14

一个方法有64K字节码大小限制

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


4
枚举怎么样?我遇到了带有大量枚举的相同问题
Toby

1
@Toby:我自己从来没有面对过这个问题。但是,其他用户在此处也发表了关于同一问题的帖子。例如-stackoverflow.com/questions/2546470可能值得研究生成的.class文件以供enum查看
大家

枚举实例(即表示常量的对象)是在类的静态初始化器中创建的,该方法是一种方法,具有相同的限制。
juancn

对于一个非常复杂的Web表单,框架生成的代码遇到了同样的问题。解决方案是将表单拆分为组件,因此还拆分了每个组件的生成代码。
SebaGra


7

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


3
(之所以投票,是因为)至少需要一个理由说明这种技术不好。提出充分的理由并不容易。
Evgeni Sergeev

2

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


1
如果他在该方法中所做的只是数组初始化,那么重构就不是一个合理的想法。
加布里埃尔·Ščerbák2010年

2
他说,他的其余代码取决于此数组。因此,他可以重构该方法,以将负责将数据加载的责任从文件/数据库传递到其他方法/工厂。
帕德玛拉格(Padmarag)2010年

您可以创建和初始化大型数组,而无需借助这种废话;参见@Kris的答案。
Stephen C

重构-“在不修改其外部功能行为的情况下更改计算机程序源代码的过程,以改善软件的某些非功能属性。” 其他答案与此有何不同?
帕德玛拉格(Padmarag)2010年

2

如其他答案所述,方法的字节码限制为64KB(至少在Sun的Java编译器中)

对我来说,将那个方法分解为更多的方法会更有意义-每个方法都会为数组分配某些相关的东西(使用ArrayList这样做可能更有意义)

例如:

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

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

或者,如果它们是固定的,例如可以从属性文件中加载,则可以从静态资源中加载它们


正确答案是将数据视为数据,将代码视为代码。
马尔科姆

@Malcolm好吧,这显然是数据,而不是代码。您的评论具有误导性,因为您不应该数据和代码混合在一起,但在这里不要将它们混合在一起。
Evgeni Sergeev

我认为这是一个很好的解决方法。我遇到了这个问题,大约21k行代码中包含7000条路由消息。我通过将这些路由消息划分为7个名称为xxx0 xxx1 xxx2的函数来解决此问题。
青铜人

2

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

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


2

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

//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();
}

1

您可以添加另一种方法来为代码创建用于额外数据空间的空间,您可能有一种方法会占用大量数据空间。尝试划分方法,因为我遇到了同样的问题,并通过在Java Android代码中为相同数据创建另一个其他方法来解决该问题,但问题解决了。


这更多是评论而不是答案。
user3071284 2015年

0

我有一个枚举会导致.java文件的大小超过500KB。Eclipse可以出于某种原因来构建它。eclipse导出的ant build.xml不能。我正在调查此事,并将更新这篇文章。


0

由于方法有大小限制,并且您现在不希望重新设计代码,因此可以将数组分成4-5个部分,然后将它们放入不同的方法中。在读取数组时,请依次调用所有方法。您还可以维护一个计数器,以了解已解析了多少个索引。


0

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


0

好的,也许这个答案为时已晚,但我认为这种方法比另一种方法更好,因此

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

  1. 打破他们

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

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

我希望这段代码对您有所帮助

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.