Mengapa Anda tidak dapat mendeklarasikan kelas sebagai statis di Java?

459

Mengapa Anda tidak dapat mendeklarasikan kelas sebagai statis di Java?

Mariselvam
sumber
72
Counter-question: apa yang Anda harapkan pengaruhnya, jika Anda mendeklarasikan sebagai kelas tingkat atas static?
Joachim Sauer
3
Tidak, Anda tidak bisa, kecuali untuk kelas dalam statis. Tapi, apa yang ingin Anda capai dengan itu?
manolowar
60
@ Joachim Sauer: Ya, C # mengartikan statickelas sebagai abstract final, yaitu, mereka tidak bisa dipakai dan tidak bisa diperpanjang. Ini berarti mereka hanya dapat berisi anggota statis, yang berguna untuk kelas yang hanya berisi metode pembantu.
bcat
30
@bcat ini berlaku untuk C #, tetapi kelas java dapat berupa abstrak atau final, bukan keduanya. Untuk mencegah suatu kelas dipakai, seseorang dapat mendeklarasikan konstruktor pribadi.
Lorenzo Polidori
7
@ JoachimSauer Sederhana, saya ingin memaksa semua anggota di kelas menjadi statis (bahkan dengan harus mendeklarasikan pada setiap metode atau properti).
hmartinezd

Jawaban:

475

Hanya kelas bersarang yang bisa statis. Dengan melakukan itu, Anda dapat menggunakan kelas bersarang tanpa memiliki instance dari kelas luar.

class OuterClass{
    public static class StaticNestedClass{
    }

    public class InnerClass{
    }

    public InnerClass getAnInnerClass(){
        return new InnerClass();
    }

    //This method doesn't work
    public static InnerClass getAnInnerClassStatically(){
        return new InnerClass();
    }
}

class OtherClass{
    //Use of a static nested class:
    private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();

    //Doesn't work
    private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();

    //Use of an inner class:
    private OuterClass outerclass= new OuterClass();
    private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
    private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}

Sumber:

Pada topik yang sama:

Colin Hebert
sumber
3
+1 meskipun frasa pertama tidak tepat. Seperti yang dinyatakan dalam tutorial, "Kelas bersarang non-statis disebut kelas dalam." (JLS: "Kelas dalam adalah kelas bertingkat yang tidak secara eksplisit atau implisit dinyatakan statis.")
user85421
74
Anda tentu saja benar; tapi saya tidak melihat bagaimana ini menjawab pertanyaan
Joeri Hendrickx
2
@Carlos Heuberger, Anda benar, saya memperbarui posting. @ Joeri Hendrickx, Pertanyaannya adalah, "mengapa sebuah kelas tidak dapat dinyatakan sebagai statis ..?", Mereka dapat, dan [baca posting saya di sini]. Ini adalah penjelasan tentang penggunaan kelas statis dan mengapa mereka harus bersarang-kelas.
Colin Hebert
1
Solusi yang diberikan di sini baik-baik saja ... Tapi saya masih bertanya-tanya y ppl belum menjelaskan secara logis bahwa kelas statis tidak mungkin di java..some penjelasan konsep OOP akan menjadi jawaban yang tepat. Saya menunggu untuk itu
Punith Raj
9
Itu benar, tetapi pertanyaan yang Anda pikirkan biasanya memecahkan sendiri ketika Anda mulai bertanya pada diri sendiri apa yang akan menjadi "kelas statis". Dalam java, elemen statis berarti bahwa Anda dapat mengakses / menjalankannya tanpa turunan dari kelas terlampir; apa artinya itu jika Anda menerapkan kata kunci ke kelas itu sendiri? Apa niat Anda? Apa yang kamu harapkan? Sekarang setelah Anda memiliki gagasan tentang apa itu bisa, saya cukup yakin bahwa itu akan menjadi "tidak benar-benar masuk akal" atau itu akan "jauh dibuat-buat" (itu akan masuk akal, tetapi pada akhirnya itu hanya sebuah pilihan yang telah dibuat).
Colin Hebert
39

Kelas tingkat atas adalah statis secara default. Kelas dalam adalah non-statis secara default. Anda dapat mengubah default untuk kelas dalam dengan secara eksplisit menandainya statis. Kelas tingkat atas, berdasarkan tingkat atas, tidak dapat memiliki semantik non-statis karena tidak ada kelas induk untuk merujuk. Oleh karena itu, tidak ada cara untuk mengubah default untuk kelas tingkat atas.

ahli nujum
sumber
14
»Kelas tingkat atas statis secara default.« Ini adalah jawaban terbaik. Mereka statis karena Anda tidak memerlukan contoh apa pun untuk merujuk mereka. Mereka dapat dirujuk dari mana saja. Mereka berada dalam penyimpanan statis (seperti dalam kelas penyimpanan C). - Seperti yang dicatat orang lain (Iain Elder dalam komentar untuk jawaban lain), perancang bahasa dapat mengizinkan statickata kunci pada kelas tingkat atas untuk menyatakan dan menegakkan bahwa itu mungkin hanya berisi anggota statis, dan tidak akan dipakai; yang dapat, bagaimanapun, membingungkan orang karena staticmemiliki arti yang berbeda untuk kelas bersarang.
Lumi
35

Jadi, saya datang terlambat ke pesta, tapi inilah dua sen saya - secara filosofis menambah jawaban Colin Hebert.

Pada tingkat tinggi, pertanyaan Anda membahas perbedaan antara objek dan tipe. Meskipun ada banyak mobil (objek), hanya ada satu kelas Mobil (tipe). Mendeklarasikan sesuatu sebagai statis berarti Anda beroperasi di ruang "ketik". Hanya ada satu. Kata kunci kelas tingkat atas sudah menentukan jenis di ruang "ketik". Akibatnya "mobil kelas statis publik" berlebihan.

Eric Jankowski
sumber
1
Iya. Dengan kata lain, kelas tingkat atas adalah statis secara default, jadi tidak perlu kata kunci.
Warren Dew
1
Yah, saya akan menambahkan apa yang dikatakan Warren Dew- "kelas tingkat atas adalah statis secara default ketika mengakses anggota statis".
Dexter
1
Jawaban yang diremehkan. Kata kunci baru untuk memaksa setiap metode di kelas menjadi statis dan konstruktor pribadi akan lebih baik. Saya tidak akan menyebutnya statis karena itu hanya membingungkan.
G_V
@G_V Meskipun java bisa membuat monster seperti itu, Java hampir membuat jalan keluar untuk membuat hal-hal bodoh menjadi sulit. Statika adalah ide yang buruk secara umum, kelas-kelas statis itu mengerikan (Lebih buruk daripada lajang yang dianggap anti-pola). Banyak orang tidak mengerti ini sehingga memberikan kata kunci akan menjadi ide yang sangat buruk. Sebaliknya, kita membuat hal-hal buruk menjadi sulit dan membiarkannya begitu saja. Perhatikan bahwa tidak ada kata kunci "Singleton" juga. dan tidak ada kata kunci Properti. Ini semua menyebabkan kode yang buruk (Meskipun orang masih menggunakan Properti begitu banyak sehingga Java mungkin juga mendukung mereka)
Bill K
29

Kelas dengan konstruktor pribadi bersifat statis.

Nyatakan kelas Anda seperti ini:

public class eOAuth {

    private eOAuth(){}

    public final static int    ECodeOauthInvalidGrant = 0x1;
    public final static int    ECodeOauthUnknown       = 0x10;
    public static GetSomeStuff(){}

}

dan Anda dapat digunakan tanpa inisialisasi:

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...
Sergey Vakulenko
sumber
3
Itu tidak statis, tetapi mengandung sifat statis. Jika Anda menulis int final publik ECodeOauthUnknown = 0x10; itu tidak statis lagi.
user1883212
9
Jika ada yang bertanya-tanya apa yang terjadi di sini, ini cocok dengan definisi C # dari "kelas statis" - msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.90%29.aspx . Dengan definisi Java tentang "kelas statis", semua kelas non-dalam adalah statis (lihat jawaban saudara).
Calum
1
Selain dari @ user1883212 benar, saya bahkan akan mengatakan bahwa jawaban ini membingungkan pembaca bahwa konstruktor pribadi entah bagaimana penting di sini, sementara itu sebenarnya tidak masalah sama sekali.
tlwhitec
Di dunia .NET, jika kelas ditandai abstrak dan final (efek dari static classdeklarasi dalam C #), kompiler bahkan tidak akan mengizinkan kode untuk mendeklarasikan variabel jenis itu, atau menggunakannya sebagai parameter tipe generik. Kurangnya konstruktor yang dapat diakses di kelas yang jika tidak dapat dipakai atau diwarisi tidak akan menghalangi deklarasi variabel dari tipe itu, atau penggunaannya sebagai parameter tipe generik.
supercat
Jawaban ini sepenuhnya salah. Konstruktor pribadi tidak ada hubungannya dengan itu. Kode hanya merupakan contoh kelas dengan apa pun kecuali atribut dan metode statis. Ini tidak ada hubungannya dengan kelas statis.
Marquis of Lorne
13

Tentu mereka bisa, tetapi hanya kelas bersarang batin . Di sana, itu berarti instance kelas bersarang tidak memerlukan instance terlampir dari kelas luar.

Tetapi untuk kelas tingkat atas, perancang bahasa tidak dapat memikirkan sesuatu yang berguna untuk dilakukan dengan kata kunci, jadi itu tidak diperbolehkan.

Michael Borgwardt
sumber
+1 meskipun frasa pertama tidak tepat. Seperti yang dinyatakan JLS: "Kelas dalam adalah kelas bersarang yang tidak secara eksplisit atau implisit dinyatakan statis." (Hanya terminologi, saya tahu ...)
user85421
7
Meskipun kelas tingkat atas tidak dapat dideklarasikan static, terkadang masuk akal untuk dapat melakukannya. Sebagai contoh, kelas yang hanya berisi metode pembantu statis tidak masuk akal untuk dipakai, tetapi bahasa Java tidak menghentikan Anda dari melakukannya. Anda bisa membuat kelas menjadi non-instantiable (dan praktis 'statis') ke kelas lain dengan mendeklarasikan konstruktor default private, yang melarang instantiasi karena tidak ada konstruktor yang terlihat.
Iain Samuel McLean Penatua
12

Anda dapat membuat kelas utilitas (yang tidak dapat membuat instance dibuat) dengan mendeklarasikan tipe enum tanpa instance. yaitu Anda secara spesifik menyatakan bahwa tidak ada instance.

public enum MyUtilities {;
   public static void myMethod();
}
Peter Lawrey
sumber
25
enumerasi sebagai tipe adalah ekspektasi spesifik: enumerasi adalah serangkaian item. Menggunakannya untuk "kelas utilitas", ketika Anda bisa saja memiliki kelas dengan konstruktor pribadi, secara semantik membingungkan.
Solusi Perangkat Lunak Visioner
5
@VisionarySoftwareSolutions Bagi saya, kekhususan ini mengatakan tidak ada instance dari kelas ini, daripada secara tidak langsung membuat tidak mungkin untuk membuat instance dari sebuah kelas.
Peter Lawrey
8
public class Outer {
   public static class Inner {}
}

... itu dapat dideklarasikan statis - selama itu adalah kelas anggota.

Dari JLS:

Kelas anggota mungkin statis, dalam hal ini mereka tidak memiliki akses ke variabel instan dari kelas sekitarnya; atau mereka mungkin kelas dalam (§8.1.3).

dan di sini:

Kata kunci statis dapat memodifikasi deklarasi tipe C anggota dalam tubuh kelas non-dalam T. Efeknya adalah untuk menyatakan bahwa C bukan kelas dalam. Sama seperti metode statis T yang tidak memiliki turunan T saat ini dalam tubuhnya, C juga tidak memiliki turunan T saat ini, juga tidak memiliki instans leksikal yang melampirkan.

Kata kunci statis tidak masuk akal untuk kelas tingkat atas, hanya karena kelas tingkat atas tidak memiliki tipe penutup.

Andreas Dolk
sumber
Jika itu bukan bagian dalam mengapa menyebutnya Inner? Nestedakan menjadi pilihan yang kurang membingungkan.
Marquis of Lorne
5

Seperti yang dijelaskan di atas, suatu Kelas tidak boleh statis kecuali jika itu adalah anggota dari Kelas lain.

Jika Anda ingin merancang kelas "yang tidak mungkin ada banyak contoh", Anda mungkin ingin melihat pola desain "Singleton".

Info Singleton Pemula di sini .

Peringatan:

Jika Anda berpikir untuk menggunakan pola singleton, lawanlah dengan sekuat tenaga. Ini adalah salah satu DesignPatterns termudah untuk dipahami, mungkin yang paling populer, dan jelas yang paling disalahgunakan. (sumber: JavaRanch sebagaimana tertaut di atas)

S.Jones
sumber
4

Selain bagaimana Java mendefinisikan kelas dalam statis, ada definisi lain dari kelas statis sesuai dengan dunia C # [1] . Kelas statis adalah kelas yang hanya memiliki metode statis (fungsi) dan dimaksudkan untuk mendukung pemrograman prosedural. Kelas semacam itu sebenarnya bukan kelas karena pengguna kelas hanya tertarik pada fungsi helper dan tidak membuat instance kelas. Sementara kelas statis didukung dalam C #, tidak ada dukungan langsung seperti itu ada di Jawa. Namun Anda dapat menggunakan enums untuk meniru kelas statis C # di Java sehingga pengguna tidak pernah dapat membuat instance dari kelas tertentu (bahkan menggunakan refleksi) [2] :

public enum StaticClass2 {
    // Empty enum trick to avoid instance creation
    ; // this semi-colon is important

    public static boolean isEmpty(final String s) {
        return s == null || s.isEmpty();
    }
}
Syams
sumber
3

Semua yang kita kode di java masuk ke kelas. Setiap kali kita menjalankan kelas JVM instantiates objek. JVM dapat membuat sejumlah objek, menurut definisi Static berarti Anda memiliki set salinan yang sama untuk semua objek.

Jadi, jika Java akan membiarkan kelas atas menjadi statis setiap kali Anda menjalankan program itu menciptakan Obyek dan terus mengesampingkan ke Lokasi Memori yang sama.

Jika Anda hanya mengganti objek setiap kali Anda menjalankannya, apa gunanya membuatnya?

Jadi itulah alasan Java menyingkirkan statis untuk Kelas Tingkat atas.

Mungkin ada alasan yang lebih konkret, tetapi ini masuk akal bagi saya.

pengguna2626445
sumber
3
Kelas dalam dikaitkan dengan kelas luar dan itulah alasan mereka bisa statis, karena Anda memiliki objek yang berbeda untuk bergantung.
user2626445
1
Maksud Anda 'itu alasan mereka tidak bisa statis'.
Marquis dari Lorne
2

Satu-satunya kelas yang bisa statis adalah kelas dalam. Kode berikut berfungsi dengan baik:

public class whatever {
    static class innerclass {
    }
}

Inti dari kelas dalam statis adalah bahwa mereka tidak memiliki referensi ke objek kelas luar.

pengguna2645256
sumber
1
'statis batin' adalah kontradiksi dalam hal. 'statis' dan 'batin' saling terpisah. Kata yang Anda cari adalah 'bersarang', bukan 'batin'.
Marquis of Lorne
1

Saya pikir ini mungkin semudah minum segelas kopi !. Coba lihat ini. Kami tidak menggunakan kata kunci statis secara eksplisit saat mendefinisikan kelas.

public class StaticClass {

    static private int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

Bukankah itu definisi kelas statis? Kami hanya menggunakan fungsi yang diikat ke kelas saja. Berhati-hatilah bahwa dalam hal ini kita bisa menggunakan kelas lain dalam sarang itu. Lihat ini:

class StaticClass1 {

    public static int yum = 4;

    static void  printHowAreYou() {
        System.out.println("How are you?");
    }
}

public class StaticClass {

    static int me = 3; 
    public static void printHelloWorld() {
       System.out.println("Hello World");
       StaticClass1.printHowAreYou();
       System.out.println(StaticClass1.yum);
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}
Erfankam
sumber
Saya pikir kita dapat mempertimbangkan kelas-kelas seperti kelas statis dengan merujuk pada definisi kelas statis bukan hanya dengan menggunakan kata kunci statis sebagai kualifikasi.
Erfankam
Pastikan untuk membuat konstruktor pribadi, atau Anda dapat mengatakannya new StaticClass()dan itu tidak masuk akal. Dengan konstruktor pribadi itu tidak akan mengizinkan hal itu.
Grinch
1

Seseorang dapat melihat PlatformUIdi Eclipse untuk kelas dengan metode statis dan konstruktor pribadi dengan dirinya sendiri bersifat final.

public final class <class name>
{
   //static constants
   //static memebers
}
pengguna175881
sumber
0

jika manfaat menggunakan kelas-statis adalah tidak membuat instance objek dan menggunakan metode kemudian hanya menyatakan kelas sebagai publik dan metode ini sebagai statis.

Eeadev
sumber