Word static in class

Multi-file variable scope example

Here I illustrate how static affects the scope of function definitions across multiple files.

a.c

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
https://stackoverflow.com/questions/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/

/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/

/* OK: extern. Will use the one in main. */
extern int i;

/* OK: only visible to this file. */
static int si = 0;

void a() {
    i++;
    si++;
    puts("a()");
    printf("i = %dn", i);
    printf("si = %dn", si);
    puts("");
}

main.c

#include <stdio.h>

int i = 0;
static int si = 0;

void a();    

void m() {
    i++;
    si++;
    puts("m()");
    printf("i = %dn", i);
    printf("si = %dn", si);
    puts("");
}

int main() {
    m();
    m();
    a();
    a();
    return 0;
}

GitHub upstream.

Compile and run:

gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o

Output:

m()
i = 1
si = 1

m()
i = 2
si = 2

a()
i = 3
si = 1

a()
i = 4
si = 2

Interpretation

  • there are two separate variables for si, one for each file
  • there is a single shared variable for i

As usual, the smaller the scope, the better, so always declare variables static if you can.

In C programming, files are often used to represent «classes», and static variables represent private static members of the class.

What standards say about it

C99 N1256 draft 6.7.1 «Storage-class specifiers» says that static is a «storage-class specifier».

6.2.2/3 «Linkages of identifiers» says static implies internal linkage:

If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.

and 6.2.2/2 says that internal linkage behaves like in our example:

In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function.

where «translation unit is a source file after preprocessing.

How GCC implements it for ELF (Linux)?

With the STB_LOCAL binding.

If we compile:

int i = 0;
static int si = 0;

and disassemble the symbol table with:

readelf -s main.o

the output contains:

Num:    Value          Size Type    Bind   Vis      Ndx Name
  5: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    4 si
 10: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 i

so the binding is the only significant difference between them. Value is just their offset into the .bss section, so we expect it to differ.

STB_LOCAL is documented on the ELF spec at http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html:

STB_LOCAL Local symbols are not visible outside the object file containing their definition. Local symbols of the same name may exist in multiple files without interfering with each other

which makes it a perfect choice to represent static.

Variables without static are STB_GLOBAL, and the spec says:

When the link editor combines several relocatable object files, it does not allow multiple definitions of STB_GLOBAL symbols with the same name.

which is coherent with the link errors on multiple non static definitions.

If we crank up the optimization with -O3, the si symbol is removed entirely from the symbol table: it cannot be used from outside anyways. TODO why keep static variables on the symbol table at all when there is no optimization? Can they be used for anything? Maybe for debugging.

See also

  • analogous for static functions: https://stackoverflow.com/a/30319812/895245
  • compare static with extern, which does «the opposite»: How do I use extern to share variables between source files?

C++ anonymous namespaces

In C++, you might want to use anonymous namespaces instead of static, which achieves a similar effect, but further hides type definitions: Unnamed/anonymous namespaces vs. static functions

Cover image for static Keyword

Hello People I hope you all are doing well, In this article I’ll be writing about the static keyword in Java.

Let’s begin…

What is word static?

The word static in the context of general language means something that is unchangeable or stable or constant. Whereas in context of programming static is a keyword, if word static is used as prefix in method name or variable name, then that will become static in nature. Something static in nature, in context of programming, is a property of class i.e., it will be initialized when the class load will happen.

In Java static keyword is used in java mainly for memory management. It is used with variables, methods, blocks and nested class. The main method of a class is generally labeled static.

public static void main(String [] args) {
    //line of code
   //line of code....
}

Enter fullscreen mode

Exit fullscreen mode

Let’s explore more about static in Java

static Variable

A variable is called a static variable when it is declared with the static keyword. In Java, a static variable is a class variable i.e., static variable shares the common property among all the objects of the same class. It saves the memory, hence, makes program memory efficient. It doesn’t have any unique value, for example, School’s name, Company’s name. Compiler does not allow static local variable.

public class Students {
    static String schoolName = "ABC Public School";
    public static void main(String [] args) {
        System.out.println("Name of school is " +schoolName);
    }
}

Enter fullscreen mode

Exit fullscreen mode

You can run your code online here

Output:-

static-keyword-java-1.png

Static variables can be accessed outside the class by calling with the class name i.e., ClassName.variableName.

i.e.,

Students.schoolName;

Enter fullscreen mode

Exit fullscreen mode

static Method

A method becomes static when it is initialized with a static keyword. It is a method which belongs to the class and not to the object. A static method can call only other static methods. We call them without creating an object of the class.

public class Students {

    static void calculatePercentage() {
        // this is a static method
    }

    void calculatePercentage() {
        // this is a non-static method
    }
}

Enter fullscreen mode

Exit fullscreen mode

Now for non-static method you will need to create object of class then invoke method

Students st = new Students();
st.calculatePercentage();

Enter fullscreen mode

Exit fullscreen mode

Whereas for static method we will invoke method without creating a new instance of the class

Students.calculatePercentage();

Enter fullscreen mode

Exit fullscreen mode

Why is the main method static?

Because program execution begins from it, and no object exists before calling it. This save lots of memory by JVM.

static Block

The static blocks are used to initialize the static data members of the class and it gets executed before the main method at the time of classloading. This is a special block that Java supports. This code inside static block is executed only once.

import java.util.Date;

public class Students {
    static {
        Date date = new Date();
        System.out.println("Today's date is :" + date);
    }
    public static void main(String [] args) {
        System.out.println("Hello");
    }
}

Enter fullscreen mode

Exit fullscreen mode

You can run your code online here

Output:-

static-keyword-java-2.png

There can be more than one static block, and they can appear anywhere in the class body. Each of them are run in the sequence of their announcement.

public class Students {
    static {
        System.out.println("Hello this is first static block");
    }
    static {
        System.out.println("Hello this is second static block");
    }
    static {
        System.out.println("Hello this is third static block");
    }
    public static void main(String [] args) {
        System.out.println("Hello this is inside main");
    }
}

Enter fullscreen mode

Exit fullscreen mode

You can run your code online here

Output:-

static-keyword-java-3.png

static Class

We can create a class within a class in Java. This is called nested class.

public class Students {

    class Marks {

    }
}

Enter fullscreen mode

Exit fullscreen mode

A nested class is marked with static modifier is called the static nested class. The static nested classes do not have access to any instance members of the enclosing outer class, the static nested classes only have access to static members of the outer class, including private ones.

public class Students {  
    static String schoolName = "ABC Public School";  
    static class Inner {  
        void name() {
            System.out.println("School name is "+ schoolName);

        }  
    }  
    public static void main(String [] args) {  
        Students.Inner st = new Students.Inner();  
        st.name();  
    }  
}  

Enter fullscreen mode

Exit fullscreen mode

You can run your code online here

Output:-

static-keyword-java-4.png

Okay so that’s enough for now follow my this journey to learn more about Java.

Thank you for reading.

Please share your thoughts about it and correct me if I’m wrong.

I hope you liked it and found it helpful.

Cover:- Rajat Gour

Connect with me on Twitter or LinkedIn

My personal blog blog.ritvikdubey.com

From Wikipedia, the free encyclopedia

Wiki letter w.svg

This article is missing information about the use of the static keyword to declare class methods in C++ and Java. Please expand the article to include this information. Further details may exist on the talk page. (April 2014)

In some programming languages such as C (and its close descendants like C++, Objective-C, and Java), static is a reserved word controlling both lifetime (as a static variable) and visibility (depending on linkage). The effect of the keyword varies depending on the details of the specific programming language.

Common C/C++ behavior[edit]

In C and C++, the effect of the static keyword in C depends on where the declaration occurs.

static may act as a storage class (not to be confused with classes in object-oriented programming), as can extern, auto and register (which are also reserved words). Every variable and function has one of these storage classes; if a declaration does not specify the storage class, a context-dependent default is used:

  • extern for all top-level declarations in a source file,
  • auto for variables declared in function bodies.
Storage class Lifetime Visibility
extern program execution external (whole program)
static program execution internal (translation unit only)
auto, register function execution (none)

In these languages, the term «static variable» has two meanings which are easy to confuse:

  1. A variable with the same lifetime as the program, as described above (language-independent); or
  2. (C-family-specific) A variable declared with storage class static.

Variables with storage class extern, which include variables declared at top level without an explicit storage class, are static in the first meaning but not the second.

Static global variable[edit]

A variable declared as static at the top level of a source file (outside any function definitions) is only visible throughout that file («file scope», also known as «internal linkage»). In this usage, the keyword static is known as an «access specifier».

Static function[edit]

Similarly, a static function – a function declared as static at the top level of a source file (outside any class definitions) – is only visible throughout that file («file scope», also known as «internal linkage»).

Static local variables[edit]

Variables declared as static inside a function are statically allocated, thus keep their memory location throughout all program execution, while having the same scope of visibility as automatic local variables (auto and register), meaning they remain local to the function. Hence whatever values the function puts into its static local variables during one call will still be present when the function is called again.

C++ specific[edit]

Static member variables[edit]

In C++, member variables declared as static inside class definitions are class variables (shared between all class instances, as opposed to instance variables).

Static method[edit]

Similarly, a static method – a method declared as static inside a class definition – is meant to be relevant to all instances of a class rather than any specific instance. A method declared as static can be called without instantiating the class.

Java[edit]

This keyword static means that this method is now a class method; it will be called through class name rather than through an object.

A static method is normally called as <classname>.methodname(), whereas an instance method is normally called as <objectname>.methodname().

See also[edit]

Все о ключевых словах static и final

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

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

Skillfactory.ru

В таком случае можно воспользоваться ключевым словом static, то есть объявить членов класса статическими. В Java большинство членов служебного класса являются статическими. Вот несколько примеров.

  • java.util.Objects содержит статические служебные операции для метода объекта.
  • java.util.Collections состоит исключительно из статических методов, которые работают с коллекциями или возвращают их.

Где можно употреблять ключевое слово static?

Мы можем использовать это ключевое слово в четырех контекстах:

  • статические методы;
  • статические переменные;
  • статические вложенные классы;
  • статические блоки.

Рассмотрим подробнее каждый из перечисленных пунктов.

Статические методы

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

public class StaticExample {
	public static void add(int a, int b) {
		System.out.println(a+b);
	}
	
	public void multiply(int a, int b) {
		System.out.println(a*b);
	}
	public static void main(String[] args) {
		/** Вызов статического метода **/
		StaticExample.add(1, 2);
		
		/** Вызов не-статического метода**/
		StaticExample staticExample = new StaticExample();
		staticExample.multiply(1, 2);
	}
}

В приведенном выше примере метод add  —  статический, поэтому его можно вызывать напрямую с именем класса. Нет необходимости создавать новый экземпляр класса StaticExample. Но метод multiply не является статическим. Таким образом, для нестатического метода необходимо создать новый экземпляр класса StaticExample.

Статические переменные

При создании объектов класса в Java каждый из них содержит собственную копию всех переменных класса.

Однако, если мы объявим переменную статической, все объекты класса будут использовать одну и ту же статическую переменную. Это связано с тем, что, как и статические методы, статические переменные также связаны с классом. И объекты класса для доступа к статическим переменным создавать не нужно. Например:

Skillfactory.ru

public class VariableExample {
public String normalVariable = null;
public static String staticVariable = null;
public static void main(String[] args) {
VariableExample firstExample = new VariableExample();
firstExample.normalVariable = "Hello";
firstExample.staticVariable = "Hello";//Это то же самое, что VariableExample.staticVariable = "Hello"
VariableExample secondExample = new VariableExample();
System.out.println("normalVariable: "+ secondExample.normalVariable);
System.out.println("staticVariable: "+ secondExample.staticVariable);
}
}

В приведенном выше примере normalVariable  —  переменная класса, а staticVariable  —  статическая переменная. Если вы объявите переменную, как показано ниже:

firstExample.staticVariable = “Hello”

Это похоже на доступ к статической переменной через имя класса:

VariableExample.staticVariable = “Hello”

Здесь статические переменные  —  переменные уровня класса. Поэтому, если вы обращаетесь к статическим переменным через переменную экземпляра объекта, то это отражается на соответствующей статической переменной уровня класса. Таким образом, статические переменные всегда имеют одно и то же значение. Но переменная экземпляра сохраняет отдельное значение в каждом экземпляре объекта. Таким образом, приведенный выше фрагмент кода выведет:

normalVariable: null

staticVariable: Hello

Статические переменные  —  редкость в Java. Вместо них применяют статические константы. Они определяются ключевым словом static final и представлены в верхнем регистре. Вот почему некоторые предпочитают использовать верхний регистр и для статических переменных.

Статические блоки

Здесь мы видим статический блок с синтаксисом:

static {

}

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

public class VariableExample {
public static String staticVariable = null;

static {
staticVariable = "Hello Variable";
}

public static void main(String[] args) {
System.out.println(staticVariable);
}
}

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

public class VariableExample {
public static String staticVariable = null;

static {
staticVariable = "Hello Variable";
}

static {
staticVariable = "Hello Again";
}

public static void main(String[] args) {
System.out.println(staticVariable);
}
}

Вывод приведенного выше фрагмента кода выглядит следующим образом, потому что переменная staticVariable обновлена вторым значением статического блока.

Hello Again

Вложенный статический класс

В Java можно объявить класс внутри другого класса. Такие классы называются вложенными классами. Они бывают двух типов: статические и нестатические.

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

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

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

public class InnerClassExample {
	public String outerElement;
	private String outerPrivateElement;
	private void outerMethod() {
		
	}
	public static class MyStaticInnerClass{
		public void myFunction() {
			System.out.println("calling static class inner function");
		}		
	}
	public class MyInnerClass {
		public void myAnotherFunction() {
			outerElement = "sample";
			outerPrivateElement ="Hello Private";
			outerMethod();
		}	
	}
	public static void main(String[] args) {
		/**Вызов статического внутренего класса **/
		InnerClassExample.MyStaticInnerClass staticInner = new InnerClassExample.MyStaticInnerClass();
		staticInner.myFunction();

		/*Вызов внутреннего класса **/
		InnerClassExample.MyInnerClass innerClass = new InnerClassExample().new MyInnerClass();
		innerClass.myAnotherFunction();		
	}
}

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

Где в памяти Java хранятся статические классы и переменные?

Вплоть до 8-й версии Java статические методы и переменные хранились в пространстве permgen. Но потом было введено новое пространство памяти, называемое метапространством  —  в нем хранятся все эти имена и поля класса, методы класса с байт-кодом методов, пул констант, JIT-оптимизации и т. д. Причина удаления permgen в Java 8.0 в том, что очень сложно предсказать необходимый размер permgen.

Зачем нужно ключевое слово final?

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

  • Конечная переменная предназначена для создания постоянных значений.
  • Конечный метод предотвращает переопределение метода.
  • Конечный класс предотвращает наследование.

Что такое конечная переменная и когда ей стоит воспользоваться?

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

Существует три способа инициализации конечной переменной.

  • Инициализировать конечную переменную, когда она будет объявлена. Это самый распространенный подход. Если конечная переменная не инициализирована при объявлении, она называется пустой конечной переменной. Ниже приведены два способа инициализации пустой конечной переменной.
  • Пустая конечная переменная может быть инициализирована внутри блока инициализатора экземпляра или внутри конструктора. Если в классе несколько конструкторов, то переменную необходимо инициализировать во всех из них, в противном случае во время компиляции появится ошибка.
  • Пустая конечная статическая переменная может быть инициализирована в статическом блоке.
public class FinalVariableExample {
	public final String MY_VARIABLE_1 = "Variable Initialized";
	public final static String MY_VARIABLE_2;
	public final String MY_VARIABLE_3;
	public final String MY_VARIABLE_4 ;
	
	static {
		MY_VARIABLE_2 = "Static Varible Initialized";
	}
	
	{
		MY_VARIABLE_3 = "block Initialized";
	}
	
	public FinalVariableExample() {
		MY_VARIABLE_4 = "Constructor Initialized";
	}		
}

Когда следует применять конечную переменную

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

Где использовать конечные классы

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

Первое, безусловно, заключается в предотвращении наследования, так как конечные классы не могут быть расширены. Например, все классы-оболочки, такие как Integer, Float и т. д.  —  конечные классы.

public final class MyFinalClass {

}

public class MyClass extends MyFinalClass{//Ошибка компиляции!!!

}

При попытке расширить конечный класс компилятор выдаст следующее исключение:

Другое применение final с классами заключается в создании неизменяемого класса, подобного предопределенному классу String. Нельзя сделать класс неизменяемым, не сделав его конечным.

Когда использовать конечные методы

Когда метод объявляется с ключевым словом final, он называется конечным методом. Такой метод не может быть переопределен. Это присутствует в классе Object  —  ряд его методов конечные. С ключевым словом final объявляются методы, для которых необходимо следовать одной и той же реализации во всех производных классах. Фрагмент ниже иллюстрирует метод с ключевым словом final:

public class MyParentClass {
public final void myFinalMethod() {
...
}
}

public class MyClass extends MyParentClass{
public final void myFinalMethod() {//Ошибка компиляции!!!
...
}
}

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

Надеемся, теперь вы хорошо поняли ключевые слова static и final.

Читайте также:

  • Используй Async/Await в JavaScript, как профессионал
  • Введение в байт-код Java
  • Жизненный цикл потока в Java

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Anish Antony: All about static and final keywords

I wrote my thoughts of static classes in an earlier thread:

I used to love utility classes filled up with static methods. They
made a great consolidation of helper methods that would otherwise lie
around causing redundancy and maintenance hell. They’re very easy to
use, no instantiation, no disposal, just fire’n’forget. I guess this
was my first unwitting attempt at creating a service oriented
architecture — lots of stateless services that just did their job and
nothing else. As a system grows however, dragons be coming.

Polymorphism

Say we have the method UtilityClass.SomeMethod that happily buzzes
along. Suddenly we need to change the functionality slightly. Most of
the functionality is the same, but we have to change a couple of parts
nonetheless. Had it not been a static method, we could make a derivate
class and change the method contents as needed. As it’s a static
method, we can’t. Sure, if we just need to add functionality either
before or after the old method, we can create a new class and call the
old one inside of it — but that’s just gross.

Interface woes

Static methods cannot be defined through interfaces for logic reasons.
And since we can’t override static methods, static classes are useless
when we need to pass them around by their interface. This renders us
unable to use static classes as part of a strategy pattern. We might
patch some issues up by passing delegates instead of interfaces.

Testing

This basically goes hand in hand with the interface woes mentioned
above. As our ability of interchanging implementations is very
limited, we’ll also have trouble replacing production code with test
code. Again, we can wrap them up but it’ll require us to change large
parts of our code just to be able to accept wrappers instead of the
actual objects.

Fosters blobs

As static methods are usually used as utility methods and utility
methods usually will have different purposes, we’ll quickly end up
with a large class filled up with non-coherent functionality —
ideally, each class should have a single purpose within the system.
I’d much rather have a five times the classes as long as their
purposes are well defined.

Parameter creep

To begin with, that little cute and innocent static method might take
a single parameter. As functionality grows, a couple of new parameters
are added. Soon further parameters are added that are optional, so we
create overloads of the method (or just add default values, in
languages that support them). Before long, we have a method that takes
10 parameters. Only the first three are really required, parameters
4-7 are optional. But if parameter 6 is specified, 7-9 are required to
be filled in as well… Had we created a class with the single purpose
of doing what this static method did, we could solve this by taking in
the required parameters in the constructor, and allowing the user to
set optional values through properties, or methods to set multiple
interdependent values at the same time. Also, if a method has grown to
this amount of complexity, it most likely needs to be in its own class
anyways.

Demanding consumers to create an instance of classes for no reason

One of the most common arguments is, why demand that consumers of our
class create an instance for invoking this single method, while having
no use for the instance afterwards? Creating an instance of a class is
a very very cheap operation in most languages, so speed is not an
issue. Adding an extra line of code to the consumer is a low cost for
laying the foundation of a much more maintainable solution in the
future. And finally, if you want to avoid creating instances, simply
create a singleton wrapper of your class that allows for easy reuse —
although this does make the requirement that your class is stateless.
If it’s not stateless, you can still create static wrapper methods
that handle everything, while still giving you all the benefits in the
long run. Finally, you could also make a class that hides the
instantiation as if it was a singleton: MyWrapper.Instance is a
property that just returns new MyClass();

Only a Sith deals in absolutes

Of course, there are exceptions to my dislike of static methods. True
utility classes that do not pose any risk to bloat are excellent cases
for static methods — System.Convert as an example. If your project is
a one-off with no requirements for future maintenance, the overall
architecture really isn’t very important — static or non static,
doesn’t really matter — development speed does, however.

Standards, standards, standards!

Using instance methods does not inhibit you from also using static
methods, and vice versa. As long as there’s reasoning behind the
differentiation and it’s standardised. There’s nothing worse than
looking over a business layer sprawling with different implementation
methods.

Понравилась статья? Поделить с друзьями:
  • Word statement of work
  • Word statement of purpose
  • Word state in french
  • Word stat yandex ru как пользоваться приложением
  • Word stat yandex ru words