Apakah memanggil konstruktor super() harus menjadi baris pertama konstruktor?

Apakah pemanggilan super() konstruktor harus menjadi baris pertama konstruktor? Jika ya, mengapa? Mengapa saya tidak dapat melakukan beberapa perhitungan sederhana dan terbatas sebelum pemanggilan konstruktor, misalnya perhitungan parameter konstruktor?

Saya menemukan situasi dengan konstruktor kelas dalam yang dapat dipanggil dengan spesifikasi penutupan:

class A {
    class Inner1 {
        Inner1() {
            // do something
        }
    }
}

class B {
    A a1 = new A();
    A a2 = new A();

    class Inner2 extends A.Inner1 {
         Inner2(boolean sel) {
             (sel?a1:a2).super();
         }
    }

}

Kasus ini menunjukkan kita ingin memilih instance terlampir untuk konstruktor kelas dasar. Mengapa logika seleksi harus dibatasi? Mengapa seseorang tidak bisa menulis sesuatu seperti ini

if( sel ) {  
    a1.super();
}
else {
    a2.super();
}

TAMBAHAN

Yang saya maksud dengan pertanyaan saya adalah batasannya bisa seperti dalam kasus berikut:

public class Base {

private final String content;

public Base(String content) {
    this.content = content;
}

public String getContent() {
    return content;
}

}


public class Derived extends Base {

public Derived(String content) {
    super(String.format("Current value of content is %s.", getContent()));
}


}

Dalam kasus terakhir saya:

1) Memenuhi syarat super() berada pada baris pertama

2) Melanggar tata tertib pembangunan

3) Dapatkan kesalahan kompiler "Tidak dapat merujuk ke metode instance saat secara eksplisit memanggil konstruktor"

Jadi, mengapa kita tidak bisa menghapuskan "persyaratan baris pertama" dan hanya mengandalkan kesalahan seperti yang terakhir?


person Suzan Cioc    schedule 23.05.2012    source sumber
comment
super() harus ditempatkan sebagai baris pertama panggilan konstruktor jika Anda menggunakannya - tetapi periksa utas ini: stackoverflow.com/questions/9675431/ atau ini: stackoverflow.com/questions/1168345/   -  person wkl    schedule 24.05.2012
comment
Terima kasih! Solusinya menarik tetapi juga menarik, mengapa Java dibuat demikian, yaitu apa salahnya jika saya melakukan sesuatu sebelum memanggil super? Misalnya, saya mungkin diwajibkan untuk tidak mengakses anggota instance sampai menelepon super.   -  person Suzan Cioc    schedule 24.05.2012
comment
@SuzanCioc Jika Anda melakukan sesuatu sebelum menelepon super(). Java akan menghentikan program Anda dan meminta Anda untuk memperbaikinya.   -  person Hunter McMillen    schedule 24.05.2012
comment
@Suzan Cioc, tautan kedua yang disediakan oleh birryree mencakup pertanyaan itu   -  person dantuch    schedule 24.05.2012
comment
@Suzan Ada bahasa (python) yang memungkinkan untuk memanggil konstruktor kelas super nanti atau tidak sama sekali. Hal ini jelas dapat menimbulkan konsekuensi yang buruk, namun kita semua tahu bahwa memanggil super() terlebih dahulu tidak menyelesaikan semua masalah dan justru menimbulkan banyak masalah baru. Ini merupakan penyederhanaan, karena ini berarti kita tidak perlu membagi alokasi dan inisialisasi objek menjadi dua bagian terpisah. Dan saya berasumsi hal ini menghindari satu jenis masalah yang mungkin sering muncul.   -  person Voo    schedule 24.05.2012
comment
Tolong lihat tambahan saya. Saya tidak ingin berurusan dengan instance yang tidak diinisialisasi seperti di C++, saya hanya bertanya-tanya, mengapa kita tidak bisa mengandalkan pemeriksaan seperti Tidak dapat merujuk ke metode instance saat secara eksplisit memanggil konstruktor?   -  person Suzan Cioc    schedule 24.05.2012


Jawaban (2)


Ya, panggilan ke super() diperlukan sebagai panggilan pertama dalam konstruktor.

Sedemikian rupa sehingga jika Anda membiarkannya, kompiler akan (mencoba) memasukkan panggilan tersebut untuk Anda. Untuk memahami alasannya, Anda perlu memahami filosofi desainer Java. Gosling selalu berada di kelompok ilmuwan komputer yang percaya bahwa mengakses objek yang diinisialisasi sebagian adalah salah satu sumber bug terbesar dalam program komputer. Dan karena itu dia merancang hierarki inisialisasi ketat yang akan membantu mengatasi masalah ini. Apakah Anda setuju dengan filosofi tersebut masih bisa diperdebatkan - tetapi penting untuk menyadari bahwa ini sama pentingnya dengan konsep di Java seperti misalnya, referensi vs pointer, atau array nyata dan terbatas. Perlu dicatat bahwa bahkan bahasa seperti Objective C yang memungkinkan Anda untuk menjalankan inisialisasi kapan saja, akan melakukan banyak upaya untuk menerapkan rantaian inisialisasi, kecuali bahwa mereka harus melakukannya melalui konvensi, bukan dengan cara yang ketat. aturan bahasa.

Saya tidak yakin apa yang ingin Anda ilustrasikan dalam contoh Anda - tetapi setelah bertahun-tahun mengembangkan Java, saya ragu Anda akan menemukan banyak kasus di mana Anda benar-benar perlu melakukan logika sebelum memanggil super.

person Perception    schedule 23.05.2012

Panggilan konstruktor dirangkai dengan super dari setiap kelas dalam hierarki dipanggil sebelum konstruktor kelas tersebut dipanggil. Karena semua kelas di Java diwarisi dari kelas objek, maka konstruktor kelas Objek dipanggil terlebih dahulu untuk setiap kelas dengan alasan alokasi memori untuk objek dilakukan oleh konstruktor kelas Objek

person ejb_guy    schedule 23.05.2012
comment
Tapi apa perbedaan mendasar jika saya menulis satu ekspresi panjang tapi tunggal dengan super() dan jika saya menulis beberapa kode multiline? - person Suzan Cioc; 24.05.2012
comment
bisakah anda jelaskan. Pada dasarnya jika konstruktor kelas Objek tidak dijalankan maka Anda tidak memiliki objek untuk dikerjakan. Dan untuk memastikan bahwa konstruktor Object dipanggil, pemanggilan super() harus menjadi baris pertama - person ejb_guy; 24.05.2012
comment
lihat pertanyaan saya, tolong. Saya menyediakan dua kode konstruktor yang diperluas, yang logikanya identik, tetapi hanya kode pertama yang diizinkan oleh Java - person Suzan Cioc; 24.05.2012