Что делает ключевое слово 'static' в классе?


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

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 378

21 ответ:

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

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

С static методы также не принадлежат конкретному экземпляру, они не могут ссылаться на члены экземпляра (как бы вы узнали, к какому экземпляру класса Hello вы хотите обратиться?). 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 или поток, но это не имеет значения.

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

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

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

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}

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

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


Примечание

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

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

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

// Clearer
Thread.sleep(5000);

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

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

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

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

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 = new Hello();
hello.staticValue = "abc";

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

Hello.staticValue = "abc";

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

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, и поэтому вы не можете получить к нему доступ из статической части класса.

статический в Java:

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

Static ключевое слово может быть использовано с:

метод

переменная

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

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

не может использоваться с:

класс (Не Вложенные)

конструктор

интерфейсы

метод локальный внутренний класс (разница затем вложенный класс)

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

Переменные

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

пример:

представьте себе следующий пример, который имеет переменная экземпляра с именем 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 остается неизменным для всего выполнения. Потому что статические члены хранятся в классе память и они загружаются только один раз за все время выполнения. Они являются общими для всех объектов класса. Если вы объявите статические переменные как окончательные, ни один из объектов не сможет изменить их значение, поскольку оно является окончательным. Поэтому переменные, объявленные как конечные и статические, иногда называются константами. Все поля интерфейсов называются константами, поскольку по умолчанию они являются конечными и статическими.

enter image description here

Изображение Ресурса : финал Статика

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

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

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

баланс должен быть отдельные, так что не статический.

enter image description here

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

в Java static ключевое слово можно просто рассматривать как указание на следующее:

"без связи или отношения к какому-либо конкретному экземпляру"

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

  • A static поле-это поле, которое принадлежит классу, а не какому-либо конкретному экземпляр

  • A static метод-это метод, который не имеет понятия this; он определен в классе и не знает о каком-либо конкретном экземпляре этого класса, если ссылка не передается ему

  • A static класс-член является вложенным классом без какого-либо понятия или знания экземпляра его заключительного класса (если ссылка на экземпляр заключительного класса не передается ему)

Static делает член clock членом класса вместо члена экземпляра. Без ключевого слова static вам нужно будет создать экземпляр класса Hello (который имеет переменную-член clock) - например,

Hello hello = new Hello();
hello.clock.sayTime();

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

я развил симпатию к статическим методам (только, если это возможно) в "вспомогательных" классах.

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

вероятно, есть и другие преимущества.

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

можно также думать о статических элементах, не имеющих указателя "this". Они являются общими для всех экземпляров.

понимание статических понятий

public class StaticPractise1 {
    public static void main(String[] args) {
        StaticPractise2 staticPractise2 = new StaticPractise2();
        staticPractise2.printUddhav(); //true
        StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */

        StaticPractise2.printUddhavsStatic1(); //true
        staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static  things and it organizes in its own heap. So, class static methods, object can't reference */

    }
}

Второй Класс

public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}

main() - это статический метод, который имеет два основных ограничения:

  1. статический метод не может использовать нестатический элемент данных или непосредственно вызывать нестатический метод.
  2. this() и super() не может использоваться в статическом контексте.

    class A {  
        int a = 40; //non static
        public static void main(String args[]) {  
            System.out.println(a);  
        }  
    }
    

Вывод: Ошибка Времени Компиляции

статические переменные могут быть доступны только в статических методах, поэтому, когда мы объявляем статические переменные, эти методы getter и setter будут статическими методами

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

ниже приведен пример для статических переменных геттеров и сеттеров:

public class Static 
{

    private static String owner;
    private static int rent;
    private String car;
    public String getCar() {
        return car;
    }
    public void setCar(String car) {
        this.car = car;
    }
    public static int getRent() {
        return rent;
    }
    public static void setRent(int rent) {
        Static.rent = rent;
    }
    public static String getOwner() {
        return owner;
    }

    public static void setOwner(String owner) {
        Static.owner = owner;
    }

}

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

при запуске этого проекта основной метод загрузки в первую очередь. Потому что его static method. Тогда это выглядит объект "a" object .Но объект a еще не определен. Потому что это не статично. Тогда приходите как эта ошибка.

//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}