2010-05-27 11 views
5

EğerStatik üye sınıfı - sınıf özel ve sınıf üyesi paket özel ilan eder misiniz?

public class OuterClass { 
    ... 

    private static class InnerClass { 
     int foo; 
     int bar; 
    } 
} 

Ben bir yerde okudum düşünüyorum şu sınıf var düşünün (ancak resmi Java Eğitimi) Ben statik üye sınıflar bildirmek olsaydı özel niteliklerini yani derleyici çeşit üretmek zorunda erişimci yöntemleri, böylece dış sınıfın statik üye sınıfına (etkin bir şekilde paket özel üst düzey sınıf) sahip olduğu özniteliklere erişebilir.

bu konuda herhangi bir fikir?

cevap

4

Evet bu doğru. En azından Sun javac için.

public class OuterClass { 

    public static void main(String... args) { 
     InnerClass.foo = 7; 
     System.out.println(InnerClass.foo); 
    } 

    private static class InnerClass { 
     private static int foo; 
     private static int bar; 
    } 
} 

$ javap -c OuterClass\$InnerClass 
Compiled from "OuterClass.java" 
class OuterClass$InnerClass extends java.lang.Object{ 
static int access$002(int); 
    Code: 
    0: iload_0 
    1: dup 
    2: putstatiC#1; //Field foo:I 
    5: ireturn 

static int access$000(); 
    Code: 
    0: getstatiC#1; //Field foo:I 
    3: ireturn 

} 

O değerini ayarlamak için bir static int access$002(int) tanımlar ve değerini almak için static int access$000(): Aşağıdaki örnekte göz at. Setter, muhtemelen someVariable = InnerClass.foo = 5'u kolayca derlemek için değeri döndürür.


$ javap -c OuterClass 
Compiled from "OuterClass.java" 
public class OuterClass extends java.lang.Object{ 
public OuterClass(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: bipush 7 
    2: invokestatiC#2; //Method OuterClass$InnerClass.access$002:(I)I 
    5: pop 
    6: getstatiC#3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    9: invokestatiC#4; //Method OuterClass$InnerClass.access$000:()I 
    12: invokevirtual #5; //Method java/io/PrintStream.println:(I)V 
    15: return 

} 

hattı 2 'de ve hat 9'da sırasıyla ayarlayıcı ( access$002) ve gaz giderici ( access$000) çağırır.


Ayrıca, gerektiğinde yalnızca bu erişim yöntemlerini tanıttığını unutmayın. Örneğin bar alan ve böylece derleyici yalnızca foo alan için bir alıcı/ayarlayıcı oluşturulan, sınıf dışından erişilebilir değildi.

+0

+1 Harika yanıt. Yani, her zaman statik üye sınıfını özel/paket-özel/korumalı olarak bildirmeli ve üye alanlarını paket-özel bırakmalısınız? – helpermethod

+1

@Helper Method - Hayır - cevabımı gör. –

+0

Söz konusu alan için uygun olanı yapmalısınız. Özel olması mantıklıysa, onu özel yapın. Önemli olana kadar performans sorunları hakkında endişelenmeyin ve daha sonra programı tamamen gözden geçirin ve optimizasyondan en fazlasını nereden aldığınızı görün. (Kesinlikle bu gibi durumlarda olmayacaktır.) – aioobe

3

bu konuda herhangi bir fikir? aioobe cevabı @

doğru olduğunu göstermektedir.

Ancak, muhtemelen hiç fark etmez. Şanslar, JIT derleyicisinin, erişim yöntemine yapılan çağrıyı yönlendirmesi ve ortaya çıkan yerel kodun basit bir getirme ile aynı olması. JIT derleyicisi bunu yapmasa bile, bir gerçek dünya uygulaması bağlamında performans cezasının önemsiz olması muhtemeldir.

Bu, noktasında numaralı bir noktanın, gerçekten ifade etmek istediğiniz şeylerden farklı bir şey söyleyen erişim değiştiricileri kullanarak kodu "optimize et" olduğunu söyler.