Static variables in C++ and Java - java

I have a question:
let's say we have this function: (in C++)
int& f() {
static int x = 0;
return x;
} // OK
and
int& h() {
int x=0;
return x;
} // ERROR
Why does h give an error? Is it because of the keyword static? I found static keyword lets my x variable live after my function is terminated. So I still can access at that memory location from the outside (another function or main? right?). Instead int x = 0 is lost after h terminates. Right? I'm not sure I really got it!
And what about Java? I read I cannot declare static variables in methods but only in classes.
Thank you.

In C++, static is one of the most overloaded keywords of the language. The meaning you're using here is this:
A variable which is defined inside a function with the static specifier has static storage duration - it occupies the same space for the entire runtime of the program, and keeps its value between different calls to the function. So you can safely return a reference to it, as the variable is always there to back the reference.
A normal (non-static) function-local variable is destroyed when the function call returns, and so the reference becomes dangling - it doesn't refer to anything valid. Using it results in Undefined Behaviour.
Java simply doesn't have function-scope static variables (it doesn't have that meaning of the keyword static). That's why you can't declare it there.
Both C++ and Java have the "class-scope" meaning of the static keyword. When a member of a class is declared with the static keyword, it means the member is not bound to any instance of the class, but is just a global variable whose identifier lives in the class's scope.

Static keyword is used for almost same purpose in both C++ and Java. There are some differences though.
1) Static Data Members: Like C++, static data members in Java are class members and shared among all objects.
2) Static Member Methods: Like C++, methods declared as static are class members and have following restrictions:
(i) They can only call other static methods.
(ii) They must only access static data.
(iii) They cannot access this or super
Like C++, static data members and static methods can be accessed without creating an object. They can be accessed using class name.
3) Static Block: Unlike C++, Java supports a special block, called static block (also called static clause) which can be used for static initialization of a class. This code inside static block is executed only once (first time you make an object of that class or the first time you access a static member of that class (even if you never make an object of that class)).
4) Static Local Variables: Unlike C++, Java doesn’t support static local variables. If used , Java program fails in compilation.
5) Static class: Classes can also be made static in Java.In java, we can’t make Top level class static. Only nested classes can be static.
Nested static class doesn’t need reference of Outer class, but Non-static nested class or Inner class requires Outer class reference.
Inner class(or non-static nested class) can access both static and
non-static members of Outer class. A static class cannot access
non-static members of the Outer class. It can access only static
members of Outer class.
Ref : www.geeksforgeeks.org

For the Java side you are correct. Static variables in Java must be declared at the class level not inside a method.
If you need to scope the static variables then you probably have some seriously broken architecture but you can do it to a certain extent by using inner classes to store the static variables in.

Static variables in C++ in functions are persistant varibles in the scope of a function. In Java, you can't have static variables in methods. Static variables are variables of the class, not its instances.

Related

what does "static" mean and the difference of it between different languages(specifically C and Java)

I am currently learning Java and C and get confused with the "static" keyword. In C I mainly use static variables as global variables. In java, I use it for initializing methods eg.
"public static void SomeMethods(){}". also for global variables within classes
eg.
public class ThisClass{
static int var=0;
public static void main(){var++;}
public static void add(){var++}
}
what does static mean and whats the difference in java and C?
The static keyword in Java is used for memory management mainly. We can apply static keyword with variables, methods, blocks and nested classes. The static keyword belongs to the class than an instance of the class.
The static can be:
Variable (also known as a class variable)
Method (also known as a class method)
Block
Nested class.
Variable :-The static variable can be used to refer to the common property of all objects (which is not unique for each object), for example, the company name of employees, college name of students, etc.
The static variable gets memory only once in the class area at the time of class loading.
Method :-A static method belongs to the class rather than the object of a class.
A static method can be invoked without the need for creating an instance of a class.
A static method can access static data member and can change the value of it.
Block :-Is used to initialize the static data member.
It is executed before the main method at the time of classloading.
For C : - check this link https://www.javatpoint.com/static-in-c#:~:text=Static%20is%20a%20keyword%20used,variable%20is%20throughout%20the%20program.

Java only static members in main class

Is it bad practice to, in the class which contains the main method, declare all members of that class as static? If so, why? Is it better to, in the main method, create a new instance of the enclosing class, and run the program from the constructor so to speak?
EDIT: (clarification)
I know the concept about static and singletons and generally when to use it. But this question regards specifically the main-class of a program. #Andrew Tobilko (who apparently removed his answer..) seems to have best understood my question judging from his answer. In my case, my main-class is about 200 LOC, and it uses two other small class (< 100 LOC each), so it's a small program. The main-class contains creating a Swing GUI and some running logic, nothing which there needs to be several instances of, so I thought I might just make everything static, to be able to use everything from the static main-method. Is this motivated? A friend who codes in C# told me using a lot of static would mean death penalty in C#. Can there be some memory problems with it or something?
It's not 'better' - it depends on what you need to do.
Declaring all the members of a class as static (including methods) simply turns the class into a singleton. If that's your use-case, then yes.
Declaring an attribute as static means that there is only one copy of this attribute which is shared by all the instances of the class.
If your use-case requires creating multiple instances, and each one of these objects should have its own "private copy" of an attribute then you shouldn't declare that attribute as static.
It's recommended to read more about the topic before you continue implementing.
Static Variables:
The static key word is used to create variables that will exist independently of any instances created for the class. Only one copy of the static variable exists regardless of the number of instances of the class.
Static variables are also known as class variables. Local variables cannot be declared static.
Static Methods:
The static key word is used to create methods that will exist independently of any instances created for the class.
Static methods do not use any instance variables of any object of the class they are defined in. Static methods take all the data from parameters and compute something from those parameters, with no reference to variables.
Class variables and methods can be accessed using the class name followed by a dot and the name of the variable or method.
static modifier are for class members. It should be only used when you want to get a single copy of instance through out the program.
Below is example to explain it,
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " +
InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " +
InstanceCounter.getCount() + " instances");
}
}
This would produce the following result:
Started with 0 instances
Created 500 instances
You could check this DuplicateQuestion for your reference
Static entity can give a call to or interact with static entities i.e. a static method can call only a static method or interact with a static variable. That is the property of static methods. Main class in java is mostly declared as "public static void main", which makes main a static method. Hence, the functions it calls are to be static.
Generally class used for constants will hold all final static
variables.
Utility classes holds all static methods.Eg - Math
class in Java

Why is it possible for objects to change the value of class variables?

By Oracle's definition,
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
So this line from the same definition is a bit confusing:
Any object can change the value of a class variable...
So I tried this code and it prints 45 (although I get a warning saying "Static member accessed via instance reference"):
public class Main {
static int value = 8;
public static void main(String[] args) {
// write your code here
Main main = new Main();
main.value = 45;
System.out.println(value);
}
}
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
It's not really that "one object" can - it's just you're in code which has access to that variable, and unfortunately Java allows you to access static members (both variables and methods) as if they were instance members. This ends up with very misleading code, e.g.
Thread t = new Thread(...);
t.start();
t.sleep(1000);
The last line looks like it's asking the newly-started thread to sleep - but actually it'll make the current thread sleep.
This is basically a flaw in Java. The compiler will silently turn code like this into
Thread.sleep(1000);
or in your case
Main.value = 45;
(I believe that in an older version of Java, it would emit code that checked for nullity with the variable you were accessing the static member "through", but it doesn't even do that any more.)
Many IDEs will allow you to flag code like this with a warning or error. I would encourage you to turn on such a feature. If you see existing code like that, change it to use access the static member directly via the declaring class, so it's clear what's going on.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No, static field is accessible for modifications, as long the access modifier allows it.
main.value = 45;
The compiler will read this line at compile-time as:
Main.value = 45;
Being able to create a class with static variables and methods so that those variables and methods are shared by all instances or objects created from the class can be very useful, see When to use static methods.
When sharing a static variable in a class between multiple instances or objects created from the class, the synchronized modifier may be required in order to ensure that if the static variable is being modified by objects in more than one thread, that data integrity is maintained, see What does synchronized mean? and also see How to synchronize a static variable among threads running different instances of a class in java.
The final key word, see How final keyword works is used to determine whether a variable is immutable or not. So if you want to have a class static variable that should be immutable or a constant then you can add the final modifier to the definition. However see Java final keyword for variables which explains that the underlying value for a reference may not be immutable in the sense that functional programming means. See also what is meant by immutable as well as Why final keyword is necessary for immutable class.
You can also use modifiers such as public to determine the visibility of variables and methods in a class, see What does public static void mean in Java.
By using modifiers such as final or private the programmer is able to finely tune the visibility and modifiability of variables in class and objects instantiated from the class.
Litle example how the compiler change the object field access to a class field access.
public class A {
static int foo = 25;
static public void main(String[] arg){
B b = new B();
A a = b;
System.out.println(b.foo);
System.out.println(a.foo);
}
}
class B extends A {
static int foo = 60;
}
The output is:
60
25
It also shows that can be confiusing as it have different behaviour as for object fields.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No. By this definition, that static variable belongs to the class and is modifiable by any instance of the class. There is no implication that when some variable is shared that it should not be modifiable. Use final if you want that.
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
To increment the value in constructor and decrement it in finalizer, for example.
A static variable has a single instance for the whole class that defines it. When an instance is created, an instance of that static variable IS NOT CREATED. There is only one, and that one is freely modifiable by any function without the need for an instance. (unless it is declared final)

about non-static class in java

My doubt is when I run the following program
public class NonStatic
{
class a
{
static int b;
}
}
The compiler is giving a error that "inner classes cannot have static declarations"
ok,then I made a change instead of "static int b" to "final static int b" its giving
same error but when I wrote "final static int b=10" means with initialization compiler
didn't complain,please can any body explain this what's the concept behind this.
it is so by design, just see the Java Language Specification: Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly declared static. [...] Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).
final static int b=10
Is interpreted as a constant so compiler can just inline it. Similarly you can have static final constants in interface.
final static int b
Is missing initialization,which is required for final member, so compiler can't quite figure what you want.
Try putting following block right after it out of curiosity:
static {
b=10;
}
Although it probably would not work...
If a field is static, there is only one copy for the entire class, rather than one copy for each instance of the class
A final field is like a constant: once it has been given a value, it cannot be assigned to again. hence when we r using final we have to assign the value to the variable.
have a look at the following link
Here is my take on this issue.
Inner class is defined as a not static member of outer class and hence, it's instance cannot exist without the instance of outer class.
The static fields of a class are accessible without creating an instance of that class.
Now if you add a static field in the inner class, that means you can access that field without create the instance of inner class BUT according to #1 instance of inner cannot exist without an instance of outer class. So this is the conflict and hence the error.
TO CROSSCHECK : Just declare the inner class static and it will correct the error.
Its because a final static variable is a constant meaning it can't change at run time, while a static variable is not a constant and can change during runtime.
So in a class static variables aren't allowed in an inner class but the constants(final) are allowed.

Local variables in java

I went through local variables and class variables concept.
But I had stuck at a doubt
" Why is it so that we cannot declare local variables as static " ?
For e.g
Suppose we have a play( ) function :
void play( )
{
static int i=5;
System.out.println(i);
}
It gives me error in eclipse : Illegal modifier for parameter i;
I had this doubt because of the following concepts I have read :
Variables inside method : scope is local i.e within that method.
When variable is declared as static , it is present for the entire class i.e not to particular object.
Please could anyone help me out to clarify the concept.
Thanks.
Because the scope of the local variables is limited to the surrounding block. That's why they cannot be referred to (neither statically, nor non-statically), from other classes or methods.
Wikipedia says about static local variables (in C++ for example):
Static local variables are declared inside a function, just like automatic local variables. They have the same scope as normal local variables, differing only in "storage duration": whatever values the function puts into static local variables during one call will still be present when the function is called again.
That doesn't exist in Java. And in my opinion - for the better.
Java doesn't have static variables like C. Instead, since every method has a class (or instance of a class) associated with it, the persistent scoped variables are best stored at that level (e.g., as private or static private fields). The only real difference is that other methods in the same class can refer to them; since all those methods are constrained to a single file anyway, it's not a big problem in practice.
Static members (variables, functions, etc.) serve to allow callers of the class, whether they're within the class or outside of the class, to execute functions and utilize variables without referring to a specific instance of the class. Because of this, the concept of a "static local" doesn't make sense, as there would be no way for a caller outside of the function to refer to the variable (since it's local to that function).
There are some languages (VB.NET, for example), that have a concept of "static" local variables, though the term "static" is inconsistently used in this scenario; VB.NET static local variables are more like hidden instance variables, where subsequent calls on the same instance will have the previous value intact. For example
Public Class Foo
Public Sub Bar()
Static i As Integer
i = i + 1
Console.WriteLine(i)
End Sub
End Class
...
Dim f As New Foo()
Dim f2 as New Foo()
f.Bar() // Prints "1"
f.Bar() // Prints "2"
f2.Bar() // Prints "1"
So, as you can see, the keyword "static" is not used in the conventional OO meaning here, as it's still specific to a particular instance of Foo.
Because this behavior can be confusing (or, at the very least, unintuitive), other languages like Java and C# are less flexible when it comes to variable declarations. Depending on how you want it to behave, you should declare your variable either as an instance variable or a static/class variable:
If you'd like the variable to exist beyond the scope of the function but be particular to a single instance of the class (like VB.NET does), then create an instance variable:
public class Foo
{
private int bar;
public void Bar()
{
bar++;
System.out.println(bar);
}
}
If you want it to be accessible to all instances of the class (or even without an instance), make it static:
public class Foo
{
private static int bar;
public static void Bar()
{
bar++;
System.out.println(bar);
}
}
(Note that I made Bar() static in the last example, but there is no reason that it has to be.)

Categories