2009-11-07 12 views
18

İş yerimde bir Java koduyla karşılaşıyorum. İşte senaryo: 2 sınıf var - ClassA ve ClassB. İçerisinde 4 adet genel statik son dize değeri dışında hiçbir şey bulunmamaktadır. Amacı ClassA.variable gibi değerleri kullanmaktır (bana neden sorma, benim kodum değil).kamu statik son değişkeni

ClassB ithalat ClassA. Dize değerlerini ClassA'da düzenledim ve derledim. ClassB koştuğumda eski değerleri kullanıyordum - yeni değerleri değil. ClassA'dan yeni değerler kullanabilmek için ClassB'u yeniden derlemeliydim! (Ben ClassA ithalatı yapan diğer sınıfları yeniden derlemek zorunda kaldım!)

Bu sadece JDK 1.6 nedeniyle mi yoksa daha önce ClassB'u yeniden derlemem gerekirdi! Beni aydınlat. sınıf ClassA den final değişkenlerin değerleri derleme zaman sabitlerini olmak olur :)

cevap

23

derleyici ClassA yerine kullanarak bir çalışma zamanı referans üreten sınıfların içine inlined olabilir. Sanırım tarif ettiğin durumda olan buydu.

Örnek: Bu örnekte,

public class Flags { 
    public static final int FOO = 1; 
    public static final int BAR = 2; 
} 

public class Consumer { 
    public static void main(String[] args) { 
     System.out.println(Flags.FOO); 
    } 
} 

derleyici muhtemelen yerine eşdeğer bir çalışma-zaman referansı üreten Consumer için oluşturulmuş koduna FOO değerini içerecektir. FOO'un değeri daha sonra değişirse, yeni değeri kullanabilmek için Consumer'u yeniden derlemeniz gerekir.

Bu, derlenmiş programın verimliliği ve hızı açısından birkaç avantajı olan bir optimizasyondur. (Burada: 1) değerini inlining Bu örnekte,

int x = Flags.FOO * 10; 

: Örneğin, değeri inlining örneğin kullanabilirsiniz ifadeler, daha optimizasyonlar etkinleştirmek olabilir, fark derleyici sağlayan çarpma yapar o Fark yok ve tamamen ihmal edilebilir.

+1

Yani, genel statik finalin derleme zamanı sabiti olduğunu mu söylüyorsunuz? bunu bilmiyordum. Sadece bir sabit olduğunu düşündüm ve çalışma zamanında değiştirilemez! yardım ettiğin için teşekkür ederim. –

+3

İyi anwser. Değişkenin satır içi olduğunu görmek istiyorsanız, sınıfın nasıl derlendiğini görmek için javap'ı kullanabilirsiniz. "javap -c Bayrakları". –

3

İkili bir uyumluluk sorunu var. Sabit alanlara yapılan referanslar derleme zamanında çözülür. Gördüğünüz davranış doğrudur; A sınıfındaki değerleri değiştirirseniz, istemciyi yeniden derlemeniz gerekecektir (B sınıfı). Bu tür sorunlardan kaçınmak için, Java sürüm 5.0'da sunulan bir enum türünü kullanarak sabitler eklemeyi düşünebilirsiniz.

2

Neden dersleri bireysel olarak derlemeye çalışıyorsunuz?

maven veya karınca gibi bir yapı sistemi kullanın ya da sadece IDE halletmesine izin.

yapmak için tek güvenli şey elde edilebilirdi her sınıf yeniden derlenmiştir kadar değişti bir java sınıfının bağlıdır her java yeniden oluşturmaktır. Eğer bir anahtar değerleri kullanmıyorsanız

+0

Sınıflardan biri veya birkaçı sizin kontrolünüzde olmayabilir. – DJClayworth

2

yerine bunu yapabilirsiniz:

public class A 
{ 
    public static final int FOO; 
    public static final String BAR; 

    static 
    { 
     FOO = 42; 
     BAR = "Hello, World!"; 
    } 
} 

sonra derleyici artık zor bunları kullanan diğer sınıflara değerleri kodlayacak.

2

varsayalım Sınıf A şuna benzer: Eğer yeniden derleyin

public class ClassA { 
    public static final int FOO = 1; 
    public static final int BAR = 2; 
} 

, ClassB eski değerleri kullanarak devam edecektir. Derleyiciye bağlı olabilir sanırım, ama bence bu tipik bir davranış. Eğer ClassB Sınıf A değişiklikler her bir sabit yeniden derlemek için istemiyorsanız, böyle bir şey yapmak gerekir:

public class ClassA { 
    public static final int FOO = CONST(1); 
    public static final int BAR = CONST(2); 

    public static int CONST(int i) { return i; } 
} 

çünkü artık Javac sabitleri satır içi istemiyor. Bunun yerine, ClassA'nın statik başlatıcısı çalıştırıldığında CONST (int) yöntemini çağırır.