Java'da "Kod çok büyük" derleme hatası


94

Java'da kod için herhangi bir maksimum boyut var mı? 10.000'den fazla satır içeren bir fonksiyon yazdım. Aslında, her satır bir dizi değişkenine bir değer atar.

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

Ve derlerken şu hatayı alıyorum: kod çok büyük

Bunu nasıl aşarım?


9
Sadece şaşkına döndüm ... Bunu yapmanın daha iyi bir yolu olmalı.
Thanos Papathanasiou

7
Bu tür şeyler için gerçekten bir veritabanına bakmanız gerekir, bu bir özellik dosyası değildir.
Paul Whelan

45
Neden zavallı adama kötü tasarım için bağırıyorsunuz? Belki OP bu çılgın yöntemi bazı kod oluşturma araçlarıyla elde etmiştir.
webuster

15
Bu sığ eleştirel yorumların çok fazla olumlu oy alması beni hayrete düşürdü!
Evgeni Sergeev

7
Derleyicinin her şeyi derleme zamanında önceden oluşturmasını sağlayabilecekken, uygulama başlangıcınız neden bazı metin dosyalarını ayrıştırarak çok zaman harcıyor? Verileri yeniden derlemeden değiştirmek veya yöntemi manuel olarak yazmak istiyorsanız bu kötü bir tasarımdır, ancak kaynak kodunu oluşturduğunuzda hiç de kötü bir tasarım değildir. (En azından bunu derleyicinin diziyi önceden oluşturmasına izin verecek şekilde yaparsanız).
Guntram Blohm

Yanıtlar:


93

Bir Java sınıfındaki tek bir yöntem, en fazla 64KB bayt kodu olabilir.

Ama bunu temizlemelisin!

.propertiesBu verileri depolamak için dosya kullanın ve şu yolla yükleyin:java.util.Properties

Bunu, .propertiesdosyayı sınıf yolunuza yerleştirerek yapabilir ve şunu kullanabilirsiniz:

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

2
"JDK / JVM'nizin gerçek boyutu ne olursa olsun"? Bu sınırın sabit olmadığını mı ima ediyorsunuz? Çünkü bu sabittir ve sınıf dosya formatı belirtimine göre gereklidir.
Joachim Sauer

1
.properties dosyasını nerede bulabilirim
trinity

1
kendinizinkini yaratır ve sonra sınıf yoluna koyarsınız
Mark

3
Önerinizi kullanmadım, ancak bir dahaki sefere denemek için sabırsızlanıyorum .. şimdi bu bilgiyi saklamak için bir veritabanı kullandım ve kodun geri kalanını buna göre değiştirdim ..
trinity

1
Bu aptalca bir soruysa özür dilerim, ama .. Bu .properties dosyası nereye koyulmalı? Demek istediğim, tamam, sınıf yolunda, ama nerede?
Milack27

14

Bir yöntemde 64K bayt kod boyutu sınırı vardır

Bunu söyledikten sonra, Richard ile aynı fikirde olmalıyım; neden bu kadar büyük bir yönteme ihtiyacınız var? OP'deki örnek verildiğinde, bir özellikler dosyası yeterli olmalıdır ... veya gerekirse bir veritabanı bile.


4
numaralandırmaya ne dersin? büyük numaralandırma kümeleriyle aynı sorunu yaşıyorum
Toby

1
@Toby: Bu sorunla kendim hiç karşılaşmadım. Yine de burada SO'da diğer kullanıcıların aynı konuyla ilgili gönderileri var. Örneğin - stackoverflow.com/questions/2546470enum Görmek için oluşturulan .class dosyasına bakmak faydalı olabilir
Herkes

Enum örnekleri (yani sabitleri temsil eden nesneler), bir yöntem olan ve aynı sınırlamaya sahip olan sınıfın statik başlatıcısında oluşturulur.
juancn

Gerçekten karmaşık bir web formu için çerçeve tarafından üretilen kodla aynı sorunla karşılaştım. Çözüm, formu bileşenlere ayırmaktı, böylece her bileşen için üretilen kod da bölündü.
SebaGra


7

Bu biraz delilik gibi görünüyor. Bir metin dosyasından veya başka bir veri kaynağından değerleri okuyarak diziyi başlatamaz mısınız?


3
(Downvoted çünkü) en az bir nedenden de bu ihtiyaçları neden böyle bir tekniktir kötü. İyi bir sebep bulmak kolay değil.
Evgeni Sergeev

3

Bu hata bazen tek bir işlevdeki çok büyük koddan kaynaklanır ... Bu hatayı çözmek için, bu işlevi birden çok işleve bölün.

//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

Kodunuzu yeniden düzenlemeyi deneyin. Java'da yöntemin boyutunda sınır vardır.


1
Bu yöntemde yaptığı tek şey dizi başlatma ise, yeniden düzenleme mantıklı bir fikir olarak görülmez.
Gabriel Ščerbák

2
Kodunun geri kalanının bunun bir dizi olmasına bağlı olduğunu söyledi. Böylece, veri yükleme sorumluluğunu dosyadan / veritabanından başka bir yönteme / Fabrikaya geçirmek için yöntemi yeniden düzenleyebilir.
Padmarag

bu tür saçmalıklara başvurmadan büyük diziler yaratabilir ve başlatabilirsiniz; @ Kris'in cevabına bakın.
Stephen C

Refactor - "Yazılımın bazı işlevsel olmayan niteliklerini iyileştirmek için harici işlevsel davranışını değiştirmeden bir bilgisayar programının kaynak kodunu değiştirme işlemi." Diğer yanıtların bundan farkı nedir?
Padmarag

2

Diğer yanıtlarda belirtildiği gibi, bir yöntem için 64KB'lik bir bayt kodu sınırı vardır (en azından Sun'ın java derleyicisinde)

Bana göre, bu yöntemi daha fazla yönteme bölmek - her biri diziye belirli ilgili şeyler atamak (bunu yapmak için bir ArrayList kullanmak daha mantıklı olabilir)

Örneğin:

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

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

Alternatif olarak, bir özellikler dosyasındaki gibi sabitlenmişlerse, öğeleri statik bir kaynaktan yükleyebilirsiniz.


Doğru cevap, veriyi veri ve kodu kod olarak ele almaktır.
Malcolm

@Malcolm Bu açıkça veridir, kod değil. Yorumunuz yanıltıcıdır, çünkü yapmamanız gereken şey verileri ve kodu karıştırmaktır , ancak burada bunlar karışık değildir.
Evgeni Sergeev

Bunun iyi bir çalışma olduğunu düşünüyorum. 21 bin satırlık kodla bu problemi içinde 7000 rota mesajıyla kesişiyorum. Bu rota mesajlarını xxx0 xxx1 xxx2 adıyla 7 fonksiyona bölerek düzeltiyorum.
bronz adam

2

Bu problemle kendim karşılaştım. Benim için işe yarayan çözüm, yöntemi yeniden düzenleme ve daha yönetilebilir parçalara indirgemekti. Sizin gibi ben de yaklaşık 10K hat yöntemiyle uğraşıyorum. Ancak, statik değişkenlerin yanı sıra daha küçük modüler fonksiyonların kullanılmasıyla sorun çözüldü.

Görünüşe göre daha iyi bir çözüm var, ancak Java 8 kullanıldığında hiçbiri yok ...


1

Ek veri alanı için kodunuz için alan oluşturmak üzere başka bir yöntem ekleyebilirsiniz, büyük miktarda veri alanı kaplayan bir yönteminiz olabilir. Yöntemlerinizi bölmeyi deneyin çünkü aynı sorunu yaşadım ve java Android kodumdaki aynı veriler için başka bir ek yöntem oluşturarak düzeltin, Sorun bunu yaptıktan sonra çözüldü.


Bu bir cevaptan çok bir yorumdur.
user3071284

0

.Java dosyasının boyutunun 500KB'nin üzerinde olmasına neden olan bir numaram var. Eclipse onu herhangi bir nedenle inşa edebilir; eclipse tarafından ihraç edilen karınca build.xml bunu yapamaz. Buna bakıyorum ve bu yazıyı güncelleyeceğim.


0

Yöntemler için bir boyut sınırı olduğundan ve şu anda kodunuzu yeniden tasarlamak istemediğinizden, diziyi 4-5 parçaya bölebilir ve sonra farklı yöntemlere koyabilirsiniz. Diziyi okurken, bir dizideki tüm yöntemleri çağırın. Kaç tane dizini ayrıştırdığınızı bilmek için bir sayaç tutabilirsiniz.


0

bu, tek yöntem çözümündeki tüm kodlardan kaynaklanmaktadır: daha fazla bazı küçük yöntemler oluşturun, sonra bu hata giderilecektir


0

tamam belki bu cevap çok geç ama bence bu yol başka bir yoldan daha iyi

örneğin, kodda 1000 satır verimiz var

  1. kır onları

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
    
  2. daha iyi performans için kodlarınıza bir "eğer" koyun

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

Umarım bu kod size yardımcı olur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.