İsimsiz bir Java yöntemini çağırmak


101

Aşağıdaki koda bakıyorum ve biraz tuhaf bir şey buldum:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

System.out"Y" ile bir yöntem bildirimine ait olmadığından, bunun bir derleme hatası vermesini beklerdim { }. Bu neden geçerlidir? Bu kodun nasıl çağrılacağını veya çağrılması gerektiğini anlamıyorum.

Bunu çalıştırırken de üretir x y c g, neden static { }sıra oluşturucusundan önce çağrılır?

Yanıtlar:


149

Bu:

static {
        System.out.print("x ");
    }

a, statik başlatma bloğu ve sınıf yüklendiğinde olarak adlandırılır. Sınıfınızda istediğiniz kadar çok olabilir ve görünüm sırasına göre (yukarıdan aşağıya) uygulanacaktır.

Bu:

    {
        System.out.print("y ");
    }

bir başlatma bloğudur ve kod, sınıfın her kurucusunun başlangıcına kopyalanır. Dolayısıyla, sınıfınızın birçok kurucusu varsa ve hepsinin başlangıçta ortak bir şey yapması gerekiyorsa, kodu yalnızca bir kez yazmanız ve bunun gibi bir başlatma bloğuna koymanız gerekir .

Dolayısıyla çıktınız mükemmel bir anlam ifade ediyor.

As Stanley aşağıda yorumladı, bkz Oracle öğretici bölüm blokları initializaiton açıklayan daha fazla bilgi için.


12
Mükemmel cevap. Başlatma bloğu hakkında daha fazla bilgiyi http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html adresinde bulabilirsiniz
Stanley

6
the code is copied into the beginning of each constructor of the class- bu yanlış. Yapıcının şununla başladığını varsayalım super("x ");, süper kurucu herhangi bir başlatma bloğundan önce çalışacaktır.
RokL

3
evet, üst yapıcıya yapılan örtük ve açık çağrılar ilk olarak yürütülecektir, sonraki başlatma bloğu ve yapıcı kodunun geri kalanı yerine.
jlordo

25

Bu bir yöntem değil, bir başlatma bloğu .

 {
    System.out.print("y ");
 }

Yapıcı çağrısından önce yürütülecektir. Süre

static {
        System.out.print("x ");
       }

olan statik başlatma blok sınıf sınıf yükleyicisi tarafından yüklendiğinde yürütülür.

Bu nedenle, kodunuzu çalıştırdığınızda
1. Sınıf, sınıf yükleyici tarafından yüklenir, böylece statik başlatma bloğu yürütülür.
Çıktı: x yazdırılır
2. Nesne oluşturulur, böylece başlatma bloğu çalıştırılır ve ardından oluşturucu olarak adlandırılır
Çıktı: y yazdırılır ve ardından c
3 gelir. Go yöntemini çağıran ana yöntem çağrılır
Çıktı: g yazdırılır

Son çıktı: xycg
Bu, http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/ yardımcı olabilir


@Cthulhu: Teşekkürler. Geçen haftaya kadar geçerliydi, yeni bağlantıyla güncelledim.
xyz

16

Bu bir örnek başlatma bloğu ve ardından statik başlatma bloğudur .

{
    System.out.print("y ");
}

sınıfın bir örneğini oluşturduğunuzda çağrılır.

static {
    System.out.print("x ");
}

sınıf, sınıf yükleyici tarafından yüklendiğinde çağrılır. Yani ne zaman yaparsan

new Sequence().go();

sınıf yüklenir, bu nedenle yürütülür static {}, ardından örnek başlatma bloğunu yürütür , daha sonra kurucunun {}gövdesi çağrılır ve ardından yeni oluşturulan örnekteki yöntem çağrılır. Çıkışı Ergo x y c g.


15
static {
        System.out.print("x ");
    }

Bir mı statik blok ve Sınıf Yükleme sırasında denir

{
    System.out.print("y ");
}

Bir başlatma bloğudur

Bir sınıfta birden çok başlatma bloğunuz olabilir, bu durumda bunlar sınıfta göründükleri sırada çalışırlar.

Sınıfta bulunan herhangi bir başlatma bloğunun yapıcıdan önce yürütüldüğüne dikkat edin.


10
static {
      System.out.print("x ");
}

sınıf tarafından paylaşılan (ile belirtildiği gibi static) ilk çalıştırılan bir başlatma bloğudur .

{
        System.out.print("y ");

}

sınıfın tüm nesneleri (kurucuları) tarafından paylaşılan ve daha sonra gelen bir başlatma bloğudur.

Sequence() {
        System.out.print("c ");
}

üçüncü olarak çalıştırılan sınıf için belirli bir kurucudur. Yapıcı her çalıştırıldığında ilk olarak örnek başlatma bloğu çağrılır. Bu yüzden "y", "c" den hemen önce gelir.

void go() {
        System.out.print("g ");
}

en son gelen, yukarıdaki yapıcı kullanılarak oluşturulan nesnelerle ilişkili bir örnek yöntemdir.


9
{
    System.out.print("y ");
}

Bu tür bloklara denir initializer block. A örneğini her oluşturduğunuzda yürütülür class. Derleme zamanında bu kod, sınıfınızın her kurucusuna taşınır.

static initializerBlok durumunda olduğu gibi : -

static {
    System.out.println("x ");
}

sınıf yüklendiğinde bir kez çalıştırılır. staticBir staticalanın başlatılması birden fazla adım gerektirdiğinde genellikle başlatıcı bloğu kullanırız .


6

Bir başlatma bloğu olarak kullanılır ve herhangi bir statik bildirimden sonra çalışır . Singleton tasarım modelinde olduğu gibi başka hiç kimsenin sınıfın bir örneğini yaratamayacağından emin olmak için kullanılabilir (aynı şekilde özel bir kurucu kullanırsınız) .


3
static {
    System.out.print("x ");
}

Static blockssınıf yüklendiğinde ve JRE tarafından başlatıldığında yalnızca bir kez yürütülür .

Ve yeni bir örnek oluşturduğunuz her seferindenon-static blok çağrı olacak ve Oluşturucu'dan hemen önce çağrılacaktır.

Burada olduğu gibi, Sequencebu şekilde oluşturulmuş tek bir örnek oluşturdunuz , non-staticbloklardan sonra çağrılmıştır ve ardından aslında amacınız olan yöntem çağrılmıştır .

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.