Использование ключевого слова static. Статические члены данных класса. Статические методы класса

Использование ключевого слова static. Статические члены данных класса. Статические методы класса


Содержание


1. Для чего в классах используются статические члены данных? Особенности использования статических членов данных

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

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

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

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

2. Как объявить статический член данных? Ключевое слово static

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

class StaticClass
{

    ...

    static type data_member;

    ...

}

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

В примере объявляется класс с именем DemoStatic. В классе объявляются две переменные-экземпляры класса или члены данных класса:

  • статическая переменная (статический член данных) класса с именем sd;
  • внутренняя переменная класса с именем d.

Также в классе объявляются методы:

  • конструктор класса, инициализирующий значение внутренних переменных класса;
  • методы доступа к статическому члену данных GetSd(), SetSD();
  • методы доступа к нестатическому члену данных GetD(), SetD();
  • статический метод DemoMethod(), демонстрирующий использование статического члена данных sd;
  • статический метод main(), который есть точкой входа в программу.

Листинг класса следующий:

// Использование класса, который содержит статический член данных
public class DemoStatic
{
    static int sd; // статический член данных - общий для всех объектов класса
    int d; // нестатический член данных

    // конструктор
    DemoStatic()
    {
        sd = 0;
        d = 0;
    }

    // методы доступа
    int GetSd()
    {
        return sd;
    }

    int GetD()
    {
        return d;
    }

    void SetSd(int nsd)
    {
        sd = nsd;
    }

    void SedD(int nd)
    {
        d = nd;
    }

    // статический метод, который демонстрирует использование статического члена данных
    static void DemoMethod()
    {
        // объявление объектов класса
        DemoStatic d1 = new DemoStatic();
        DemoStatic d2 = new DemoStatic();
        DemoStatic d3 = new DemoStatic();
        int t; // дополнительная переменная

        t = d1.GetD(); // t = 0
        t = d1.GetSd(); // t = 0

        // изменение статического члена данных
        d1.SetSd(5);
        t = d2.GetSd(); // t = 5 - статический член данных есть общим для объектов d1, d2, d3
        t = d3.GetSd(); // t = 5 - так же

        // изменение нестатического члена данных
        d1.SedD(8);
        t = d2.GetD(); // t = 0

        System.out.println(t);
    }

    public static void main(String[] args)
    {
        DemoMethod();
    }
}

4. Какая общая форма объявления статического метода в классе?

Равно как и статический член данных класса, статический метод в классе объявляется с помощью ключевого слова static.

В простейшем случае объявления класса с статическим методом имеет следующий общий вид:

class StaticClass
{
    // ...

    static type StaticMethod(parameters)
    {
        // ...
    }

    // ...
}

где

  • StaticClass – имя класса, в котором объявляется статический метод;
  • StaticMethod() – статический метод.

5. Какие ограничения накладываются на статические методы?

На статические методы, которые объявлены в некотором классе, накладываются следующие требования:

  • статические методы могут вызвать только другие статические методы;
  • статические методы имеют доступ только к статическим переменным. К нестатическим переменным класса статические методы доступа не имеют;
  • статические методы не могут ссылаться на ссылку this класса;
  • статические методы не могут использовать ссылки типа super.



6. Можно ли использовать объект класса в нестатическом методе класса, если в классе этого объекта объявляется статический член данных?

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

Cannot make a static reference to the non-static method DemoMethod() from the type DemoStatic

где

  • DemoMethod() – нестатический метод;
  • DemoStatic – статический класс.

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

7. Могут ли статические переменные объявляться как скрытые с ключевым словом private?

Да, могут. В примере в п. 3 статический член класса можно объявлять так:

private static int sd; // статический член данных, объявленный как private

 

8. Что такое статический блок класса? Для чего используется статический блок класса?

Статический блок класса имеет следующий общий вид:

static
{
    // тело блока
    // ...
}

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

 

9. Пример класса, в котором осуществляется инициализация статической переменной разными способами

Способ 1. С помощью оператора присваивания ‘=’.

// инициализация статического члена данных класса - способ 1
public class InitStatic
{
    static double sd=2.85; // инициализация статического члена

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        InitStatic s1 = new InitStatic(); // вызывается конструктор
        double x;

        x = s1.sd; // x = 2.85
        x = sd; // x = 2.85

        System.out.println(x);
    }
}

Способ 2. С помощью конструктора.

// инициализация статического члена данных класса - способ 2
public class InitStatic
{
    static double sd;

    // инициализация с помощью конструктора
    InitStatic()
    {
        sd = -8.893;
    }

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        InitStatic s1 = new InitStatic(); // вызывается конструктор
        double x;

        x = s1.sd; // x = -8.893
        x = sd; // x = -8.893

        System.out.println(x);
    }
}

 Способ 3. Инициализация с помощью статического блока.

// инициализация статического члена данных класса - способ 3
public class InitStatic
{
    static double sd; // инициализация статического члена

    // инициализация с помощью статического блока
    static
    {
        sd = -100.0;
    }

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        InitStatic s1 = new InitStatic(); // вызывается конструктор
        double x;

        x = s1.sd; // x = -100.0
        x = sd; // x = -100.0

        System.out.println(x);
    }
}

10. Как доступиться к статическому методу (переменной) за пределами его класса? Как вызвать статический метод (переменную) используя имя класса, в котором он реализован. Пример

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

ClassName.StaticMethod()

где

  • ClassName – имя класса, в котором объявлен статический метод;
  • StaticMethod() – имя статического метода.

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

ClassName.StaticVariable

где

  • ClassName – имя класса, в котором объявлена статическая переменная;
  • StaticVariable – имя статической переменной.

 

Пример. В нижеследующем примере объявляется 2 класса с именами A и B. В классе A реализована статическая переменная и статический метод. Демонстрируется вызов статических переменной и метода класса B из класса A.

Реализация класса B:

public class B
{
    static int b; // статическая переменная

    // статический блок инициализации переменной b
    static
    {
        b = 13;
    }

    // статический метод
    static int GetB()
    {
        return b;
    }
}

Реализация класса A:

public class A
{
    // статическая переменная
    static int a;

    // конструктор класса
    A()
    {
        a = 5;
    }

    // статический метод
    static int GetA()
    {
        return a;
    }

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        // доступ к статической переменной по имени класса A
        A.a = 8;

        int t;

        // доступ к статическому методу класса A
        t = A.GetA(); // t = 8

        // доступ к статической переменной класса B
        t = B.b; // t = 13 - переменная инициализирована с помощью статического блока класса B
        B.b = 33;
        t = B.b; // t = 33

        // доступ к статическому методу класса B
        t = B.GetB(); // t = 33

        System.out.println(t);
    }
}


Связанные темы