Что делает ключевое слово static в классе? - PullRequest
421 голосов
/ 05 января 2009

Если быть точным, я пытался этот код:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

Но это дало ошибку

Невозможно получить доступ к нестатическому полю в статическом методе main

Поэтому я изменил объявление clock на следующее:

static Clock clock = new Clock();

И это сработало. Что значит поставить это ключевое слово перед объявлением? Что именно он будет делать и / или ограничивать с точки зрения того, что можно сделать с этим объектом?

Ответы [ 21 ]

602 голосов
/ 05 января 2009

static члены принадлежат классу, а не конкретному экземпляру.

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

Поскольку static методы также не принадлежат конкретному экземпляру, они не могут ссылаться на члены экземпляра. В данном примере main не знает, на какой экземпляр класса Hello (и, следовательно, на какой экземпляр класса Clock) он должен ссылаться. static участники могут ссылаться только на static участников. Участники экземпляра могут, конечно, иметь доступ к static членам.

Примечание: Конечно, static члены могут получить доступ к элементам экземпляра через ссылку на объект .

Пример:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1]: в зависимости от характеристик среды выполнения он может быть по одному на ClassLoader или AppDomain или поток, но это не относится к делу.

129 голосов
/ 05 января 2009

Это означает, что в Hello имеется только один экземпляр «clock», а не по одному на каждый отдельный экземпляр класса «Hello», или, более того, это означает, что среди всех будет одна общая ссылка «clock» все экземпляры класса «Hello».

Так что, если вы хотите сделать «новый Hello» в любом месте вашего кода: A- в первом сценарии (до изменения, без использования «static»), он будет делать новые часы каждый раз, когда вызывается «new Hello», но B- во втором сценарии (после изменения с использованием «статического») каждый экземпляр «нового Hello» по-прежнему будет использовать и использовать исходную и ту же самую ссылку «часы», которая была создана впервые.

Если вам не нужны "часы" где-то за пределами основного, это будет работать так же хорошо:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}
96 голосов
/ 04 июля 2009

Ключевое слово static означает, что что-то (поле, метод или вложенный класс) связано с типом , а не с каким-либо конкретным экземпляром типа. Так, например, каждый вызывает Math.sin(...) без какого-либо экземпляра класса Math, и в действительности вы не можете создать экземпляр класса Math.

Для получения дополнительной информации см. соответствующий бит Oracle Tutorial .


Sidenote

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

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

Это заставляет выглядеть , как будто sleep является методом экземпляра, но на самом деле это статический метод - всегда делает текущий поток спящим. Лучше прояснить это в коде вызова:

// Clearer
Thread.sleep(5000);
40 голосов
/ 04 июля 2009

Ключевое слово static в Java означает, что переменная или функция являются общими для всех экземпляров этого класса, поскольку они принадлежат типу , а не самим фактическим объектам.

Таким образом, если у вас есть переменная: private static int i = 0; и вы увеличиваете ее (i++) в одном случае, изменение будет отражено во всех случаях. i теперь будет 1 во всех случаях.

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

24 голосов
/ 13 марта 2014

Базовое использование статических элементов ...

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}

Таким образом, вы можете иметь общие значения для всех членов класса без отправки экземпляра класса Hello другому классу И, кроме статики, вам не нужно создавать экземпляр класса.

Hello hello = new Hello();
hello.staticValue = "abc";

Вы можете просто вызывать статические значения или методы по имени класса:

Hello.staticValue = "abc";
20 голосов
/ 14 августа 2016

Статическое в Java:

Static - модификатор отсутствия доступа. Ключевое слово static относится к классу, а не к экземпляру класса. может использоваться для присоединения переменной или метода к классу.

Статическое ключевое слово МОЖЕТ использоваться с:

Метод

Variable

Класс, вложенный в другой класс

Блок инициализации

НЕ МОЖЕТ использоваться с:

Класс (не вложенный)

Конструктор

Интерфейсы

Метод Local Inner Class (отличие от вложенного класса)

методы внутреннего класса

Переменные экземпляра

Локальные переменные

Пример:

Представьте себе следующий пример, в котором есть переменная экземпляра с именем count , которая увеличивается в конструкторе:

package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

Выход:

1 1 1

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

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

package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

Выход:

1 2 3

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

Статика с финалом:

Глобальная переменная, объявленная как final и static , остается неизменной на протяжении всего выполнения. Потому что статические члены хранятся в памяти классов и загружаются только один раз за все выполнение. Они являются общими для всех объектов класса. Если вы объявите статические переменные как окончательные, любой из объектов не сможет изменить их значение, поскольку оно является окончательным. Поэтому переменные, объявленные как final и static, иногда называют константами. Все поля интерфейсов называются константами, поскольку по умолчанию они являются окончательными и статическими.

enter image description here

Изображение Ресурс: Окончательный статический

19 голосов
/ 05 января 2009

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

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

напрямую, вместо:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

Внутри статического метода (который принадлежит классу) вы не можете получить доступ к любым элементам, которые не являются статическими, так как их значения зависят от вашего экземпляра класса. Нестатический объект Clock, являющийся членом экземпляра, будет иметь разные значения / ссылки для каждого экземпляра вашего класса Hello, и поэтому вы не можете получить к нему доступ из статической части класса.

13 голосов
/ 18 июля 2016

Чтобы добавить к существующим ответам, позвольте мне попробовать с изображением:

Процентная ставка 2% применяется ко ВСЕМ сберегательным счетам. Следовательно это статический .

Баланс должен быть индивидуальным , поэтому он не статический.

enter image description here

13 голосов
/ 05 января 2009

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

7 голосов
/ 05 января 2009

Поле может быть назначено либо классу, либо экземпляру класса. По умолчанию поля являются переменными экземпляра. При использовании static поле становится переменной класса, таким образом, есть один и только один clock. Если вы вносите изменения в одном месте, это видно везде. Varables экземпляра меняются независимо друг от друга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...