Почему вы не можете объявить класс как static в Java?

Почему вы не можете объявить класс как static в Java?

14 ответов


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

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

источники :

по теме :


Итак, я опаздываю на вечеринку, но вот мои два цента, - философски добавляет к ответу Колина Хеберта.

на высоком уровне ваш вопрос касается разницы между объектами и типами. Хотя есть много автомобилей (объектов), есть только один класс автомобилей (тип). Объявление чего-либо как статического означает, что вы работаете в пространстве "тип". Есть только один. Ключевое слово класса верхнего уровня уже определяет тип в пространстве "тип". В результате " public static класс автомобиля " является избыточным.


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


класс с частным конструктором является статическим.

объявите свой класс следующим образом:

public class eOAuth {

    private eOAuth(){}

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

}

и вы можете использовать без инициализации:

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...

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

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


вы можете создать класс утилиты (который не может иметь созданных экземпляров), объявив тип перечисления без экземпляров. т. е. вы конкретно заявляете, что нет экземпляров.

public enum MyUtilities {;
   public static void myMethod();
}

public class Outer {
   public static class Inner {}
}

... он может быть объявлен static - пока это член класса.

из JLS:

классы-члены могут быть статическими, и в этом случае они не имеют доступа к переменным экземпляра окружающего класса; или они могут быть внутренними классами (§8.1.3).

и здесь:

ключевое слово static может изменить объявление типа члена C в теле не-внутреннего класса T. свое влияние к объявите, что C не является внутренним классом. точно так же, как статический метод T не имеет текущего экземпляра T в своем теле, C также не имеет текущего экземпляра T и не имеет лексически охватывающих экземпляров.

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


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

Если вы хотите создать класс, "которого не может быть несколько экземпляров", вы можете заглянуть в шаблон дизайна" Singleton".

начинающий Синглтон информация здесь.

предостережение:

Если вы думаете об использовании в шаблон singleton, сопротивляться со всеми твоя мощь. Это один из самых простых DesignPatterns в понимаете, наверное самый популярный, и определенно наиболее жестоко. (источник: JavaRanch, как указано выше)


в дополнение к тому, как Java определяет статические внутренние классы, есть еще одно определение статических классов согласно c# world [1]. Статический класс-это класс, который имеет только статические методы (функции) и предназначен для поддержки процедурного программирования. Такие классы на самом деле не являются классами, поскольку пользователь класса заинтересован только в вспомогательных функциях, а не в создании экземпляров класса. Хотя статические классы поддерживаются в C#, в Java такой прямой поддержки не существует. Однако вы можете использовать перечисления для имитации статических классов C# в Java, чтобы пользователь никогда не мог создавать экземпляры данного класса (даже используя отражение) [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();
    }
}

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

public class whatever {
    static class innerclass {
    }
}

точка статических внутренних классов заключается в том, что они не имеют ссылки на объект внешнего класса.


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

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

Если вы просто заменяете объект каждый раз, когда вы запускаете его, в чем смысл создания это?

Так вот почему Java избавилась от статики для класса верхнего уровня.

могут быть более конкретные причины, но это имело для меня много логического смысла.


Я думаю, что это можно так же легко, как выпить стакан кофе!. Просто взгляните на это. Мы не используем ключевое слово static явно при определении класса.

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

это не определение статического класса? Мы просто используем функцию, привязанную только к классу. Будьте осторожны,чтобы в этом случае мы могли использовать другой класс в этом вложенном. Посмотрите на это:

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

можно посмотреть PlatformUI в Eclipse для класса со статическими методами и частным конструктором, который сам по себе является окончательным.

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

Если преимущество использования static-class не заключалось в создании экземпляра объекта и использовании метода, просто объявите класс как public, а этот метод как static.