Что делает ключевое слово 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 ответов


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

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

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


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

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

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

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

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

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


Sidenote

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

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

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

// Clearer
Thread.sleep(5000);

на 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
}

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

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


Static в 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

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

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

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

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

Static с Final:

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

enter image description here

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


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


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

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

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

enter image description here


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


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

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

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

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

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

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


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

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

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


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

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

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


ключевое слово 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. Тогда это выглядит object "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
    }
}