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

7
이런 유형의 데이터베이스를 살펴보면 속성 파일이 실패합니다.
Paul Whelan

45
왜 당신들은 나쁜 디자인에 대해 불쌍한 녀석에게 소리를 지르십니까? OP는 일부 코드 생성 도구로 미친 방법을 얻었을 것입니다.
webuster 2014-08-09

15
이 얕은 비판적 댓글이 너무 많은 찬성표를 얻은 것에 놀랐습니다!
Evgeni Sergeev 2014

7
컴파일러가 컴파일 타임에 모든 것을 미리 생성하도록 할 수 있는데 왜 애플리케이션 시작이 일부 텍스트 파일을 구문 분석하여 많은 시간을 소비합니까? 재 컴파일하지 않고 데이터를 변경하거나 메서드를 수동으로 작성하려는 경우 나쁜 디자인이지만 소스 코드를 생성하는 경우에는 전혀 나쁜 디자인이 아닙니다. (적어도 컴파일러가 배열을 미리 생성 할 수있는 방식으로 수행하는 경우).
Guntram Blohm

답변:


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

1
.properties 파일은 어디서 찾을 수 있습니까?
trinity

1
당신은 당신의 자신의 다음 클래스 패스에 넣어 만들
마크

3
나는 당신의 제안을 사용하지 않았다. 그러나 나는 다음에 그것을 시도하고 싶다 .. 이제이 정보를 저장하기 위해 데이터베이스를 사용했고, 그에 따라 나머지 코드를 수정했다 ..
trinity

1
어리석은 질문이라면 미안하지만 ..이 .properties 파일을 어디에 넣어야합니까? 내 말은, 그것은 클래스 경로에 있지만 어디에 있습니까?
Milack27 2015 년

14

메서드 에 64K 바이트 코드 크기 제한이 있습니다.

그렇게 말했지만, 나는 리처드와 동의해야합니다. 왜 그렇게 큰 방법이 필요한가요? OP의 예가 주어지면 속성 파일로도 충분하거나 필요한 경우 데이터베이스로도 충분합니다.


4
열거 형은 어떻습니까? 큰 열거 형 집합에서 동일한 문제가 발생합니다
Toby

1
@Toby : enum으로이 문제에 직면 한 적이 없습니다. 그래도 같은 문제에 대한 다른 사용자의 게시물이 있습니다. 예를 들어 - stackoverflow.com/questions/2546470 는 것은 생성 된 .class 파일을 조사 할 가치가있을 수 있습니다 enum보고
모두

Enum 인스턴스 (즉, 상수를 나타내는 개체)는 메서드이며 동일한 제한이있는 클래스의 정적 이니셜 라이저에서 생성됩니다.
juancn

정말 복잡한 웹 양식에 대한 프레임 워크 생성 코드에서 동일한 문제에 직면했습니다. 해결책은 구성 요소에서 양식을 분할하는 것이 었으므로 각 구성 요소에 대해 생성 된 코드도 분할되었습니다.
SebaGra

13

에 따르면 Java 가상 머신 사양 , 메소드의 코드는보다 큰 65536 바이트 안 :

code_length항목 의 값은 code이 메서드 에 대한 배열 의 바이트 수를 제공합니다 .

code_length의 값은 0보다 크고 (코드 배열이 비어 있지 않아야하므로) 65536보다 작아야합니다.

code_lengthcode[]메소드의 실제 바이트 코드를 포함 하는 속성 의 크기를 정의합니다 .

code배열 방법을 구현하는 자바 가상 머신 코드의 실제 바이트를 제공합니다.


7

이것은 광기처럼 보입니다. 텍스트 파일이나 다른 데이터 소스에서 값을 읽어 배열을 초기화 할 수 없습니까?


3
(이유로 비추천) 이러한 기술이 나쁜 이유가 하나 이상 필요합니다 . 타당한 이유를 찾는 것은 쉽지 않습니다.
Evgeni Sergeev 2014

3

이 오류는 단일 함수에서 너무 큰 코드로 인해 가끔 발생합니다.이 오류를 해결하려면 해당 함수를 다음과 같이 여러 함수로 분할하십시오.

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

2

코드를 리팩터링하십시오. Java에서는 메소드 크기에 제한이 있습니다.


1
리팩토링은 그가 그 메소드에서하는 모든 것이 배열 초기화라면 합리적인 아이디어로 이어지지 않습니다.
Gabriel Ščerbák 2010 년

2
그는 나머지 코드는 이것이 배열에 달려 있다고 말했습니다. 따라서 그는 파일 / 데이터베이스에서 다른 메서드 / Factory로 데이터를로드하는 책임을 전달하도록 메서드를 리팩터링 할 수 있습니다.
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

@Malcolm 글쎄, 이것은 코드가 아니라 분명히 데이터입니다. 당신이하지 말아야 할 것은 데이터와 코드를 혼합 하는 것이기 때문에 당신의 의견은 잘못된 것 입니다.
Evgeni Sergeev 2014

나는 이것이 좋은 해결 방법이라고 생각합니다. 나는 7000 개의 경로 메시지가있는 약 21k 줄의 코드 로이 문제와 교차합니다. 그 경로 메시지를 이름이 xxx0 xxx1 xxx2 인 7 기능으로 div하여 수정합니다.
청동 남자

2

나는이 문제에 직접 부딪쳤다. 나를 위해 일한 솔루션은 방법을 더 관리하기 쉬운 부분으로 리팩토링하고 축소하는 것이 었습니다. 당신처럼 저는 거의 10K 라인 방법을 다루고 있습니다. 그러나 정적 변수와 더 작은 모듈 식 함수를 사용하여 문제가 해결되었습니다.

더 나은 해결 방법이있을 것 같지만 Java 8을 사용하면 아무것도 없습니다.


1

추가 데이터 공간을위한 코드 공간을 생성하는 다른 방법을 추가 할 수 있습니다. 많은 양의 데이터 공간을 차지하는 방법이있을 수 있습니다. 동일한 문제가 있었기 때문에 방법을 나누고 Java Android 코드에서 동일한 데이터에 대해 다른 추가 방법을 만들어 수정하십시오. 그 후에 문제가 사라졌습니다.


이것은 답변 이라기보다는 코멘트에 가깝습니다.
user3071284

0

.java 파일의 크기가 500KB를 초과하는 열거 형이 있습니다. 이클립스는 어떤 이유로 든 그것을 빌드 할 수있다. eclipse-exported 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();
    }
    

이 코드가 도움이 되었기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.