Статические классы в Java

Есть что-нибудь подобное static class в яве?

В чем смысл такого класса. У всех методов статического класса должны быть static тоже?

Требуется ли наоборот, если класс содержит все статические методы, должен ли класс быть статическим?

Для чего нужны статические классы?

14 ответов

Решение

В Java есть статические вложенные классы, но, похоже, вы ищете статический класс верхнего уровня. В Java нет способа сделать класс верхнего уровня статическим, но вы можете имитировать статический класс следующим образом:

  • Объявите свой класс final - Предотвращает расширение класса, поскольку расширение статического класса не имеет смысла
  • Сделай конструктор private - Предотвращает создание экземпляров клиентским кодом, так как нет смысла создавать экземпляры статического класса.
  • Сделайте все члены и функции класса static - Поскольку класс не может быть создан, нельзя вызывать методы экземпляра или получить доступ к полям экземпляра
  • Обратите внимание, что компилятор не помешает вам объявить экземпляр (нестатический) член. Эта проблема появится, только если вы попытаетесь вызвать экземпляр экземпляра.

Простой пример согласно предложениям сверху:

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;
    }
}

Что хорошего в статических классах? Хорошее использование статического класса - это определение одноразовых, служебных и / или библиотечных классов, в которых создание экземпляров не имело бы смысла. Отличным примером является класс Math, который содержит некоторые математические константы, такие как PI и E, и просто предоставляет математические вычисления. Требование инстанцирования в таком случае было бы ненужным и запутанным. Смотрите Java Math класс. Обратите внимание, что он является окончательным и все его члены статичны. Если бы Java позволяла классам верхнего уровня объявляться как статические, тогда класс Math действительно был бы статическим.

Ну, у Java есть "статические вложенные классы", но они совсем не похожи на статические классы C#, если вы туда пришли. Статический вложенный класс - это всего лишь тот, который неявно не имеет ссылки на экземпляр внешнего класса.

Статические вложенные классы могут иметь методы экземпляра и статические методы.

В Java нет такого понятия, как статический класс верхнего уровня.

Существует статический вложенный класс, этот [статический вложенный] класс не нуждается в экземпляре включающего класса для того, чтобы его можно было создать.

Эти классы [статические вложенные] могут обращаться только к статическим членам включающего класса [так как он не имеет никакой ссылки на экземпляры включающего класса...]

Пример кода:

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(); 
  }
}

Да, в Java есть статический вложенный класс. Когда вы объявляете вложенный класс статическим, он автоматически становится отдельным классом, который может быть создан без создания экземпляра внешнего класса, к которому он принадлежит.

Пример:

public class A
{

 public static class B
 {
 }
}

Так как class B объявляется статическим, вы можете явно создать экземпляр как:

B b = new B();

Обратите внимание, если class B не был объявлен статическим, чтобы сделать его автономным, вызов объекта экземпляра выглядел бы так:

A a= new A();
B b = a.new B();

Что происходит, когда члены внутри class объявлен как static..? Это члены могут быть доступны без создания class, Поэтому создание внешнего класса (класс верхнего уровня) static не имеет смысла. Поэтому это не разрешено.

Но вы можете установить внутренние классы как статические (так как они являются членами класса верхнего уровня). Затем к этому классу можно получить доступ без создания экземпляра класса верхнего уровня. Рассмотрим следующий пример.

public class A {
    public static class B {

    }
}

Теперь внутри другого класса C, учебный класс B можно получить доступ без создания экземпляра класса A,

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

static классы могут иметь non-static участники тоже. Только класс становится статичным.

Но если static ключевое слово удалено из класса B, он не может быть доступен напрямую без создания экземпляра A,

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

Но мы не можем иметь static члены внутри non-static внутренний класс.

Может ли класс быть статическим в Java?

Ответ ДА, у нас может быть статический класс в Java. В Java у нас есть статические переменные экземпляра, а также статические методы, а также статический блок. Классы также можно сделать статическими в Java.

В Java мы не можем сделать класс верхнего уровня (внешний) статическим. Только вложенные классы могут быть статическими.

статический вложенный класс против нестатического вложенного класса

1) Вложенный статический класс не нуждается в ссылке на внешний класс, но нестатический вложенный класс или внутренний класс требует ссылки на внешний класс.

2) Внутренний класс (или нестатический вложенный класс) может обращаться как к статическим, так и к нестатическим членам класса Outer. Статический класс не может получить доступ к нестатическим членам класса Outer. Он может получить доступ только к статическим членам класса Outer.

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

Видя, что это лучший результат в Google для "статического класса Java", и лучший ответ здесь не здесь, я решил добавить его. Я интерпретирую вопрос OP относительно статических классов в C#, которые известны как синглтоны в мире Java. Для тех, кто не знает, в C# ключевое слово "static" может быть применено к объявлению класса, что означает, что результирующий класс никогда не может быть создан.

Отрывок из "Эффективного Java - Второе издание" Джошуа Блоха (который считается одним из лучших доступных руководств по стилю Java):

Начиная с версии 1.5, существует третий подход к реализации синглетонов. Просто создайте тип enum с одним элементом:

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

Этот подход функционально эквивалентен общедоступному полевому подходу, за исключением того, что он более лаконичен, предоставляет механизм сериализации бесплатно и обеспечивает железную гарантию от множественных реализаций, даже перед сложными атаками сериализации или отражения. Хотя этот подход еще не получил широкого распространения, одноэлементный тип перечисления является лучшим способом реализации синглтона. (выделение автора)

Блох, Джошуа (2008-05-08). Эффективная Java (Java Series) (стр. 18). Пирсон Образование.

Я думаю, что реализация и обоснование довольно очевидны.

Внешние классы не могут быть статическими, но могут быть вложенные / внутренние классы. Это в основном помогает вам использовать вложенный / внутренний класс без создания экземпляра внешнего класса.

Проще говоря, Java поддерживает объявление класса статичным только для внутренних классов, но для классов верхнего уровня.

классы верхнего уровня: проект Java может содержать более одного класса верхнего уровня в каждом исходном файле Java, один из классов назван в честь имени файла. Перед классами верхнего уровня разрешены только три параметра или ключевые слова: public, abstract и final.

Внутренние классы: классы, которые находятся внутри класса верхнего уровня, называются внутренними классами, что в основном является концепцией вложенных классов. Внутренние классы могут быть статичными. Идея сделать статические внутренние классы состоит в том, чтобы воспользоваться преимуществами создания экземпляров объектов внутренних классов без создания экземпляра объекта класса верхнего уровня. Это точно так же, как статические методы и переменные работают внутри класса верхнего уровня.

Следовательно, Java поддерживает статические классы на уровне внутреннего класса (во вложенных классах)

И Java не поддерживает статические классы на классах верхнего уровня.

Я надеюсь, что это дает более простое решение вопроса для базового понимания статических классов в Java.

Вы не можете использовать ключевое слово static с классом, если это не внутренний класс. Статический внутренний класс - это вложенный класс, который является статическим членом внешнего класса. Доступ к нему можно получить без создания экземпляра внешнего класса с использованием других статических членов. Как и статические члены, статический вложенный класс не имеет доступа к переменным экземпляра и методам внешнего класса.

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();
   }
}

Есть ли что-нибудь вроде статического класса в Java?

Синглтоны похожи на статический класс. Я удивлен, что о них еще никто не упомянул.

      public final class ClassSingleton { 

private static ClassSingleton INSTANCE;
private String info = "Initial info class";

private ClassSingleton() {        
}

public static ClassSingleton getInstance() {
    if(INSTANCE == null) {
        INSTANCE = new ClassSingleton();
    }
    
    return INSTANCE;
}

// getters and setters

public String getInfo(){
    return info;
  }
}

Использование выглядит примерно так:

      String infoFromSingleton = ClassSingleton.getInstance().getInfo()

Синглтоны отлично подходят для хранения ArrayLists / List / Collection Classes / и т. Д. Если вы часто собираете, обновляете, копируете коллекции из нескольких областей и вам необходимо синхронизировать эти коллекции. Или многие к одному.

В Java есть статические методы, которые связаны с классами (например, java.lang.Math имеет только статические методы), но сам класс не является статическим.

Все хорошие ответы, но я не видел ссылки на java.util.Collections, который использует тонны статического внутреннего класса для своих методов статического фактора. Итак, добавляем то же самое.

Добавление примера из java.util.Collections, который имеет несколько статических внутренних классов. Внутренние классы полезны для группировки кода, доступ к которому должен осуществляться через внешний класс.

/**
 * @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();}
}

Вот метод статического фактора в классе java.util.Collections

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}

Статический метод означает, что к нему можно получить доступ без создания объекта класса, в отличие от 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
  }
}
Другие вопросы по тегам