Klasy statyczne w Javie

947

Czy jest coś takiego static classw java?

Jakie jest znaczenie takiej klasy. Czy wszystkie metody klasy statycznej też muszą być static?

Czy wymagane jest na odwrót, że jeśli klasa zawiera wszystkie metody statyczne, to klasa również powinna być statyczna?

Do czego służą klasy statyczne?

Kraken
źródło
4
Możesz być zainteresowany stackoverflow.com/questions/3584113/java-static-class
Ishtar
Klasy statyczne są zasadniczo używane do grupowania klas razem.
RockingDev

Odpowiedzi:

847

Java ma klasy zagnieżdżone statycznie, ale wygląda na to, że szukasz klasy statycznej najwyższego poziomu. Java nie ma możliwości uczynienia statycznej klasy najwyższego poziomu, ale można symulować klasę statyczną w następujący sposób:

  • Zadeklaruj swoją klasę final- Zapobiega rozszerzeniu klasy, ponieważ rozszerzenie klasy statycznej nie ma sensu
  • Make the constructor private- Zapobiega tworzeniu instancji według kodu klienta, ponieważ nie ma sensu tworzyć instancji klasy statycznej
  • Utwórz wszystkie elementy i funkcje klasy static- Ponieważ nie można utworzyć instancji klasy, nie można wywoływać metod instancji ani uzyskiwać dostępu do pól instancji
  • Zauważ, że kompilator nie uniemożliwi Ci zadeklarowania członka instancji (niestatycznego). Problem pojawi się tylko wtedy, gdy spróbujesz zadzwonić do członka instancji

Prosty przykład według sugestii z góry:

public class TestMyStaticClass {
     public static void main(String []args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); // results in compile time error
     }
}

// A top-level Java class mimicking static class behavior
public final class MyStaticClass {
    private MyStaticClass () { // private constructor
        myStaticMember = 1;
    }
    private static int myStaticMember;
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

Co dobrego mają klasy statyczne? Dobrym zastosowaniem klasy statycznej jest definiowanie klas jednorazowych, użytkowych i / lub bibliotecznych, w których tworzenie instancji nie miałoby sensu. Świetnym przykładem jest klasa Math, która zawiera pewne stałe matematyczne, takie jak PI i E, i po prostu zapewnia obliczenia matematyczne. Wymaganie wystąpienia w takim przypadku byłoby niepotrzebne i dezorientujące. Zobacz Mathklasę i kod źródłowy . Zauważ, że tak jest finali wszyscy jej członkowie static. Jeśli Java zezwala na deklarowanie klas najwyższego poziomu, staticwówczas klasa Math byłaby rzeczywiście statyczna.

Paul Sasik
źródło
34
klasa Fooz jedynymi staticmetodami nie jest taka sama jakstatic class Foo
craigb
12
@Evorlor: Jeśli klasa zostanie uznana za końcową, wówczas jej metody są automatycznie (skutecznie) ostateczne. Wynika to z faktu, że klasy końcowej nie można podklasować, a zatem jej metody nie mogą zostać zastąpione (tzn. Są faktycznie ostateczne). docs.oracle.com/javase/tutorial/java/IandI/final.html
jwayne
30
Ta odpowiedź może dotyczyć znaczenia OP, ale (obecnie) nie wyjaśnia klas statycznych Java, a zatem w ogóle nie odpowiada na pytanie! Jest to bardzo złe dla ludzi, którzy przybywają tutaj, próbując dowiedzieć się, co oznacza klasa statyczna w Javie.
Tom
12
@JBoy: Istnieje coś takiego jak „klasa statyczna” w Javie, o co chodzi w tym pytaniu, ale ta odpowiedź wcale nie wyjaśnia. Zamiast tego wyjaśnia, jak symulować w Javie, co odpowiedź nazywa „klasą statyczną” - ale nie jest to „klasa statyczna” w Javie! (Być może jest to tak zwana „klasa statyczna” w innym języku (językach), ale ludzie przybywający tutaj, aby dowiedzieć się o klasach statycznych Java, zostaną wprowadzeni w błąd i zmieszani.)
Tom
4
powinieneś wyraźnie wspomnieć, że prywatny MyStaticClass () {// prywatny konstruktor myStaticMember = 1; } nie będzie miało żadnego efektu, ponieważ konstruktor nie zostanie wywołany. Ale nie o to chodzi. Nadal jestem bardzo zdezorientowany co do użyteczności statycznych klas wewnętrznych w Javie oraz ich użyteczności lub wartości dodanej.
Mołdawia
315

Cóż, Java ma „statyczne klasy zagnieżdżone”, ale wcale nie są takie same jak klasy statyczne w C #, skąd pochodzisz. Statycznie zagnieżdżona klasa to tylko taka, która nie ma niejawnie odniesienia do wystąpienia klasy zewnętrznej.

Statycznie zagnieżdżone klasy mogą mieć metody instancji i metody statyczne.

W Javie nie ma czegoś takiego jak klasa statyczna najwyższego poziomu.

Jon Skeet
źródło
12
W Javie Dlaczego statyczna klasa zagnieżdżona dopuszcza metody instancji? Jakie jest zastosowanie metody instancji w takiej klasie?
Geek
19
@Geek: Czy przeczytałeś moją odpowiedź? Przeczytaj uważnie drugie zdanie. Dlaczego nie chcesz mieć metod instancji klas statycznych? W końcu możesz tworzyć ich wystąpienia.
Jon Skeet,
17
@Geek: Tak, jest to całkowicie dopuszczalne. Twoje „zrozumienie”, że klasy statyczne są klasami użyteczności, jest zasadniczo błędne. Nie to w ogóle oznacza statyczne klasy w Javie.
Jon Skeet
14
@Geek: Tak. Dokładnie tak, jak napisałem w mojej odpowiedzi: „Statycznie zagnieżdżona klasa to tylko taka, która nie ma pośrednio odniesienia do instancji klasy zewnętrznej”.
Jon Skeet
6
@KhurramAli: Czy masz na myśli niejawnie ? Z pewnością nie są one wyraźnie statyczne, biorąc pod uwagę, że nie używasz słowa kluczowego staticpodczas ich deklarowania. Są domyślnie statyczne, ponieważ nie potrzebujesz odniesienia do niczego innego, aby je zbudować. Osobiście uważam, że statyczna / niestatyczna terminologia jest nieco dziwna dla klas zagnieżdżonych ... Myślę, że łatwiej byłoby mówić o tym, jakie jest zachowanie.
Jon Skeet
157

Istnieje statyczna klasa zagnieżdżona , ta klasa [statycznie zagnieżdżona] nie potrzebuje instancji klasy zamykającej, aby mogła zostać utworzona instancja.

Te klasy [statyczne zagnieżdżone] mogą uzyskiwać dostęp tylko do statycznych elementów klasy zamykającej [ponieważ nie ma żadnego odniesienia do instancji klasy zamykającej ...]

przykładowy kod:

public class Test { 
  class A { } 
  static class B { }
  public static void main(String[] args) { 
    /*will fail - compilation error, you need an instance of Test to instantiate A*/
    A a = new A(); 
    /*will compile successfully, not instance of Test is needed to instantiate B */
    B b = new B(); 
  }
}
amit
źródło
1
Czy możemy więc powiedzieć, że możemy używać wewnętrznych klas statycznych w celu tworzenia ich instancji bez potrzeby ich upubliczniania?
Mołdawia
@moldovean Używamy wewnętrznych klas statycznych w celu utworzenia ich z kontekstu statycznego (takiego jak main). Nie sądzę, żeby miało to związek z widocznością.
Michael Dorst,
2
@moldovean static / non static jest ortogonalny do widoczności. Możesz mieć dowolny rodzaj widoczności, zarówno statyczny, jak i niestatyczny. Chodzi o to, czy potrzebujesz instancji klasy zamykającej, aby utworzyć klasę wewnętrzną?
amit
103

Tak, w Javie jest statycznie zagnieżdżona klasa. Gdy zadeklarujesz klasę zagnieżdżoną jako statyczną, automatycznie staje się ona klasą samodzielną, którą można utworzyć instancji bez konieczności tworzenia instancji klasy zewnętrznej, do której należy.

Przykład:

public class A
{

 public static class B
 {
 }
}

Ponieważ class Bjest zadeklarowany jako statyczny, możesz jawnie utworzyć instancję jako:

B b = new B();

Zauważ, że jeśli class Bnie został zadeklarowany jako statyczny, aby stał się samodzielny, wywołanie obiektu instancji wyglądałoby tak:

A a= new A();
B b = a.new B();
Mapa bitowa
źródło
7
zwróć uwagę, że możesz tworzyć instancję klasy niestatycznej regularnie, tak B b = new B();jakbyś próbował utworzyć instancję z Asamej klasy .
Muhammed Refaat
33

Co się dzieje, gdy członkowie wewnątrz classsą zadeklarowani jako static…? Do członków można uzyskać dostęp bez tworzenia instancji class. Dlatego tworzenie klasy zewnętrznej (klasa najwyższego poziomu) staticnie ma znaczenia. Dlatego nie jest dozwolone.

Ale możesz ustawić klasy wewnętrzne jako statyczne (ponieważ jest to członek klasy najwyższego poziomu). Następnie można uzyskać dostęp do tej klasy bez tworzenia klasy najwyższego poziomu. Rozważ następujący przykład.

public class A {
    public static class B {

    }
}

Teraz wewnątrz innej klasy można uzyskać dostęp do Cklasy Bbez tworzenia instancji klasy A.

public class C {
    A.B ab = new A.B();
}

staticklasy mogą mieć non-staticrównież członków. Tylko klasa staje się statyczna.

Ale jeśli staticsłowo kluczowe zostanie usunięte z klasy B, nie będzie można uzyskać do niego bezpośredniego dostępu bez wykonania instancji A.

public class C {
    A a = new A();
    A.B ab = a. new B();
}

Ale nie możemy mieć staticczłonków w non-staticwewnętrznej klasie.

Ramesh-X
źródło
Czy możemy utworzyć instancję klasy statycznej, czy ma to sens?
Supun Wijerathne,
6
Nie tak jak w innych językach, staticma tylko jedno znaczenie w java. Jeśli coś jest staticw klasie, oznacza to, że można do niego uzyskać dostęp bez tworzenia instancji tej klasy. Nie mówi nic o tworzeniu instancji czy nie ...
Ramesh-X
Przepraszam, przepełnienie stosu! W tym przypadku nie mogę odmówić podziękowania Ramesh-X! Omówiłeś prawie wszystko, co zastanawiałem się nad statycznymi klasami wewnętrznymi i klasami wewnętrznymi.
Mołdawia
Nie można „ustawić klas wewnętrznych jako statycznych”. Jest to sprzeczność w kategoriach . Zagnieżdżona klasa jest wewnętrzna lub statyczna.
user207421,
13

Biorąc pod uwagę, że jest to najlepszy wynik w Google dla „java klasy statycznej” i najlepszej odpowiedzi nie ma tutaj, pomyślałem, że go dodam. Interpretuję pytanie OP dotyczące klas statycznych w języku C #, które są znane jako singletony w świecie Java. Dla nieświadomych w języku C # słowo kluczowe „static” można zastosować do deklaracji klasy, co oznacza, że ​​klasy wynikowej nigdy nie można utworzyć.

Fragment „Effective Java - Second Edition” Joshua Blocha (powszechnie uważany za jeden z najlepszych dostępnych przewodników po stylu Java):

Od wersji 1.5 istnieje trzecie podejście do implementacji singletonów. Po prostu stwórz typ wyliczeniowy z jednym elementem:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

Podejście to jest funkcjonalnie równoważne z podejściem publicznym, z wyjątkiem tego, że jest bardziej zwięzłe, zapewnia maszynerię do serializacji za darmo i zapewnia żelazną gwarancję przeciwko wielokrotnemu tworzeniu instancji, nawet w obliczu wyrafinowanych ataków serializacji lub odbicia. Chociaż podejście to nie zostało jeszcze powszechnie przyjęte, jednoelementowy typ wyliczenia jest najlepszym sposobem na wdrożenie singletonu. (podkreślenie autora)

Bloch, Joshua (2008-05-08). Skuteczna Java (Java Series) (s. 18). Edukacja Pearson.

Myślę, że wdrożenie i uzasadnienie są dość oczywiste.

Bennet Huber
źródło
6
Dobry sposób na wdrożenie Singletona. Niestety, pytanie nie dotyczy Singletonów, chodzi o klasy statyczne
David SN
1
Java ma raczej unikalną interpretację słowa kluczowego „static”. Wygląda na to, że OP pochodzi z C #, gdzie „klasa statyczna” jest odpowiednikiem singletona w Javie. Zaktualizowałem swoją odpowiedź, aby wyjaśnić tę interpretację pytania.
Bennet Huber,
1
Klasa statyczna AC # nie jest singletonem. Instancja Singleton jest obiektem i może implementować interfejs, co oznacza, że ​​może uczestniczyć we wstrzykiwaniu zależności i może być wyśmiewana. Klasa statyczna AC # nie może zaimplementować interfejsu ani zostać wstrzyknięta w jakikolwiek sposób, i jest znacznie bliższa tylko kilku funkcjom języka C, i oczywiście umożliwia metody rozszerzenia.
Novaterata
13

Czy klasa może być statyczna w Javie?

Odpowiedź brzmi TAK , możemy mieć klasę statyczną w Javie. W Javie mamy statyczne zmienne instancji , jak i metody statyczne , a także blok statyczny . Klasy mogą być również ustawione na statyczne w Javie.

W Javie nie możemy ustawić statycznej klasy zewnętrznej (zewnętrznej). Tylko zagnieżdżone klasy mogą być statyczne.

statyczna klasa zagnieżdżona vs niestatyczna klasa zagnieżdżona

1) Zagnieżdżona klasa statyczna nie potrzebuje odwołania do klasy zewnętrznej, ale niestatyczna klasa zagnieżdżona lub klasa wewnętrzna wymaga odniesienia do klasy zewnętrznej.

2) Klasa wewnętrzna (lub niestatyczna klasa zagnieżdżona) może uzyskać dostęp zarówno do statycznych, jak i niestatycznych elementów klasy zewnętrznej. Klasa statyczna nie może uzyskać dostępu do niestatycznych elementów klasy zewnętrznej. Może uzyskiwać dostęp tylko do statycznych członków klasy zewnętrznej.

patrz tutaj: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

roottraveller
źródło
również wewnętrzne klasy „niestatyczne” nie mogą deklarować pól ani metod statycznych
Mr.Cat
2

Mówiąc prościej, Java obsługuje deklarację, że klasa jest statyczna tylko dla klas wewnętrznych, ale nie dla klas najwyższego poziomu.

klasy najwyższego poziomu: Projekt Java może zawierać więcej niż jedną klasę najwyższego poziomu w każdym pliku źródłowym Java, przy czym jedna z klas nosi nazwę po nazwie pliku. Przed klasami najwyższego poziomu dozwolone są tylko trzy opcje lub słowa kluczowe: publiczny, abstrakcyjny i końcowy .

Klasy wewnętrzne: klasy należące do klasy najwyższego poziomu nazywane są klasami wewnętrznymi, co jest w zasadzie pojęciem klas zagnieżdżonych. Klasy wewnętrzne mogą być statyczne . Ideą statyczną dla klas wewnętrznych jest wykorzystanie instancji obiektów klas wewnętrznych bez tworzenia obiektu klasy najwyższego poziomu. Jest to dokładnie ten sam sposób, w jaki metody statyczne i zmienne działają wewnątrz klasy najwyższego poziomu.

Dlatego Java obsługuje klasy statyczne na poziomie klasy wewnętrznej (w klasach zagnieżdżonych)

A Java nie obsługuje klas statycznych w klasach najwyższego poziomu.

Mam nadzieję, że daje to prostsze rozwiązanie pytania o podstawowe zrozumienie klas statycznych w Javie.

Saichand
źródło
0

Java ma metody statyczne, które są powiązane z klasami (np. Java.lang.Math ma tylko metody statyczne), ale sama klasa nie jest statyczna.

duffymo
źródło
0

Nie można używać słowa kluczowego static z klasą, chyba że jest to klasa wewnętrzna. Statyczna klasa wewnętrzna jest klasą zagnieżdżoną, która jest statycznym członkiem klasy zewnętrznej. Można uzyskać do niego dostęp bez tworzenia instancji klasy zewnętrznej, używając innych elementów statycznych. Podobnie jak elementy statyczne, statyczna klasa zagnieżdżona nie ma dostępu do zmiennych instancji i metod klasy zewnętrznej.

public class Outer {
   static class Nested_Demo {
      public void my_method() {
          System.out.println("This is my nested class");
      }
   }
public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();
      nested.my_method();
   }
}
Nahid Nisho
źródło
Nie można używać staticsłowa kluczowego z klasą, chyba że jest to klasa zagnieżdżona . „Statyczny wewnętrzny” jest wewnętrznie sprzecznością .
user207421,
0

Metoda statyczna oznacza, że ​​można uzyskać do niej dostęp bez tworzenia obiektu klasy, w przeciwieństwie do public:

public class MyClass {
   // Static method
   static void myStaticMethod() {
      System.out.println("Static methods can be called without creating objects");
   }

  // Public method
  public void myPublicMethod() {
      System.out.println("Public methods must be called by creating objects");
   }

  // Main method
  public static void main(String[ ] args) {
      myStaticMethod(); // Call the static method
    // myPublicMethod(); This would output an error

    MyClass myObj = new MyClass(); // Create an object of MyClass
    myObj.myPublicMethod(); // Call the public method
  }
}
dJack
źródło
Nie odpowiada na pytanie.
user207421,
-1

Wszystkie dobre odpowiedzi, ale nie widziałem odwołania do java.util.Collections, który używa ton statycznej klasy wewnętrznej do swoich metod współczynników statycznych. Więc dodając to samo.

Dodanie przykładu z java.util.Collections, który ma wiele statycznych klas wewnętrznych. Klasy wewnętrzne są przydatne do grupowania kodu, do którego należy uzyskać dostęp za pośrednictwem klasy zewnętrznej.

/**
 * @serial include
 */
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                             implements Set<E>, Serializable {
    private static final long serialVersionUID = -9215047833775013803L;

    UnmodifiableSet(Set<? extends E> s)     {super(s);}
    public boolean equals(Object o) {return o == this || c.equals(o);}
    public int hashCode()           {return c.hashCode();}
}

Oto metoda współczynnika statycznego w klasie java.util.Collections

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}
Jay Rajput
źródło
Nie dostałeś komentarza? Czy możesz rozwinąć? Próbuję zrozumieć twój komentarz.
Jay Rajput