Local variables in java - 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.)

Related

Accessing variables from multiple methods in java

I'm starting to learn java, and I don't fully understand class variables and instance variables. I've seen some StackOverflow posts about accessing a variable from multiple methods, and most of the answers say to use static class variables. My question is, why can't one just use private instance variables? What are the advantages of using one over the other?
Instance variables are only accessible from instance functions (i. e. from non-static functions). Under the OOP paradigm, most of your variables will likely be instance variables.
Class variables (static) can also be accessed from class functions (static), like your main function.
Say, you have a class called Car. Every instance of this class (say, myFerrari and myBeetle) has its own variables doors, engine, gearbox et cetera. Thus, they are non-static, as are functions like drive (because you are driving an individual car, not the concept of cars).
But you might have a static variable MAX_ALLOWED_PASSENGERS which tells you how many seats a car may have before it's considered a bus instead. This is tied to the concept of cars (i. e. the class), not to any individual car. Thus, it might be static.
As a beginner, depending on your method of learning, you may not yet understand OOP and only write procedural code - which is not what Java is designed for. Thus you may encounter weirdnesses, like code examples where all functions and variables are static. This is a side effect of using Java in an unintended way and its purpose will be clear to you later on.
You can think of a static variable as a shared variable between all instances of the class. It is mostly used when you have a need of common value to be accessible across all objects of the class. Look at below example and execute it. It will clarify things. Please note that I have accessed a static variable with instance which is not the right practice but it is for demonstration purpose only.
public class A{
static int counter=1;
private int value;
public A(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
public class B{
public static void main(String[] args){
A a1 = new A(10);
A a2 = new A(12);
System.out.println(a1.value);
System.out.println(a2.value);
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
A.counter=20;
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
}
}
Notice how changing value of counter in class A impacts the result for both variables.
Ok first of all you should in most cases use instance variable.
class variables (static variable) are used when you need one instance across the whole class.
meaning if you have 2 different objects the static variable will be used for both of them, while using instance variable means that each object will hold its own vriable with its own value.
example:
public class Test{
public static int classVar=1;
public int instanceVar;
}
now this code will yield different resulkt based on the variable used:
Test o1=new Test();
o1.instanceVar=1;
Test o2=new Test();
o2.instanceVar=2;
System.out.println("class var object 1"+o1.classVar);//will result in 1 and warn that shoud be used as class level there for as Test.classVar
System.out.println("instance var object 1"+o1.classVar);//will result in 1
System.out.println("class var object 1"+o2.classVar);//will result in 1
System.out.println("instance var object 1"+o2.classVar);//will result in 2

Use Of Static variables in java?

I mean we know that Static members should only belongs to the Class,and not part of the any object created from the class . but we can also access static methods via objects right? lets say getInstaceCount() is the static member of Class CharStack.
for example I can create object here and access Static member of CharStack :
CharStack stack1 = new Charstack(10);// declaring object
int count1 = stack1.getinstanceCount();//accessing Static member with the object
so above I can also access the static member of Charstack with object stack1,so my doubt is what is the exact use of Static member if its even accessible by its object ?similarly why instance variable of a class is not accessible by Class ?
A static method doesn't make any sense with respect of a specific instance of a class.
The fact that invoking a static method on an instance is allowed shouldn't fool you: it just a design error of Java language which makes no sense.
A static method doesn't have a this reference so it makes no sense to be able to invoke it on a specific instance.
in addition a static method is not polymorphic so in any case you can't exploit this fact by calling it on an instance
Short story: static methods make sense in certain situations, but you should always call them through the class, eg CharStakc.getInstanceCount() to clarify their intended behavior, since being allowed to invoke them through instances is just a bad choice which shouldn't be allowed at all.
similarly why instance variable is not accessible by Class ?
Say you have this class:
class Foo{
public static Bar barStatic;
public Bar barInstance;
public static void main(String[] args){
Foo foo=new Foo();
Bar barInstance=Foo.barInstance;//case 1
Bar barStatic=foo.barStatic;// case 2
.....
}
}
Now in case 1 you want to access some object's instance variable. But which object? One, more or no objects of the class Foo might be in the heap. But based on what should the runtime decide which object to choose (if one exists of course).
But in case 2, even though you say foo.barStatic compiler is "smart enough" to know that foo is an instance of Foo and interprets your foo.barStatic as Foo.barStatic when you compile the code. I definitely don't like this design, it's confusing. So, you should know that everything is fine under the hood, it's just during code design it doesn't complain although as others have noted, good IDE's will warn you to follow the preferred Foo.barStatic way.
The static variable gets memory only once in class area at the time of class loading.
It makes your program memory efficient (i.e it saves memory).
The static variable can be used to refer the common property of all objects (that is not unique for each object) e.g. company name of employees,college name of students etc.

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)

private variables in java?

I was watching a tutorial on youtube and the topic was private variables. We usually set variables in java like this:
class hello {
public static void main(String args[]) {
String x;
x = "Hello"
}
}
but in that tutorial, the string type was declared out of the method like this:
class hello {
private String x;
public void apples() {
x = "this is a private variable.";
System.out.println(x);
}
}
As you can see it was not the main method, but i want to ask that do private variables always have to be out of method or what?
I am a beginner so this will be really helpful to know as i don't want to cram up knowledge to prevent confusion and also because it is a matter of fact that people who cram up code never become a good programmer.
do private variables always have to be out of method or what?
That's right. A variable inside a method is a local variable and can not have any access modifiers such as private, public or protected. These modifiers can only be applied to member variables, i.e. variables that are declared in the class scope.
If you think about it, it makes a lot of sense, since local variables can't be accessed by another class anyway. Not even another object of the same class or another method in the same object.
Related question:
What is the difference between a member variable and a local variable?
Cass variables must be declared to be one of the following types:
Public
Protected
Public
In the first example, the variable is local to the function: that is, it's specifically bound to method hello.main().
In that case, it's only accessible within that method function. It's not a class variable, so it doesn't need its access level to be set.
In the second example, the variable is a class variable. When you have a class variable, you can set it to private (can only be accessed by an object of that class), protected (accessed by inherited classes), or public (can be accessed outside of the object). The many methods possible inside the class can then access that class variable.
When you have a variable set inside a class definition, and not inside a method, it is called a "field" or "property" or "attribute." The way you define the accessibility of the field is required since multiple methods within the class can refer to it.
When you have a variable set within any method, it can only be accessed inside of that method, and can't be accessed outside (unless you use a reference pointer or pass it through method arguments).
A private variable in Java is a variable Globally accessible to the class and only to that class (and of course any other methods in the containing class).
A variable declared within a method can be accessed only within the scope of the method. A variable declared inside an if statement is only accessible inside the if statement .... and so on.
Its best to have as little private variable as possible because of performance issues. Lets say you have 100 private variables declared in a class. Your class contains 10 methods and each method utilizes 10 variables. When instantiating an object then your object is created instantiating olso the 100 private variables. If you make you variables local to your methods, then no variable is created on instantiation of the class, and 10 variables are used each time you access a method....
There are also other types of variables in java, to better comprehend you can start from here http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html
I think what's confusing you is the distinction between a local variable (declared in a method), and a member variable (declared in a class, outside of the class's methods).
A local variable exists just while the method that it's declared in is running. It comes into existence at the point that it's declared, then goes out of scope later, when the next } character occurs (other than those that match { characters that aren't opened yet). This effectively means that the variable disappears in a puff of smoke - it can't be used once it's gone out of scope.
But a member variable lives inside an object. That means it gets created when the object is created, and destroyed when the object is destroyed. So it typically lives for a much longer duration than the local variables do. Member variables can sometimes be used by objects other than the object that they belong to; and there are some quite complex rules around when it's possible to do this.
The private modifier on a member variable just means that it can only be accessed by code that's in the class that the object belongs to.
but i want to ask that do private variables always have to be out of method or what?.
Well, It doesn't make sense actually to make a variable private in a method. Because variables declared in a method are stack variables and they have narrower scope than a private one. As they can be accessed only in the method they are declared in and private variables have scope in the whole class they are declared in.
Any variable created with in a scope ( code block bounded inside { } ) is a local variable of that scope; and not accessible out side the block.
Also private variables is term which comes into picture when you talk about classes and define a member which is not accessible outside class.

method local innerclasses accessing the local variables of the method

Hi I was going through the SCJP book about the innerclasses, and found this statement, it goes something like this.
A method local class can only refer to the local variables which are marked final
and in the explanation the reason specified is about the scope and lifetime of the local class object and the local variables on the heap, but I am unable to understand that. Am I missing anything here about final??
The reason is, when the method local class instance is created, all the method local variables it refers to are actually copied into it by the compiler. That is why only final variables can be accessed. A final variable or reference is immutable, so it stays in sync with its copy within the method local object. Were it not so, the original value / reference could be changed after the creation of the method local class, giving way to confusing behaviour and subtle bugs.
Consider this example from the JavaSpecialist newsletter no. 25:
public class Access1 {
public void f() {
final int i = 3;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(i);
}
};
}
}
The compiler turns the inner class into this:
class Access1$1 implements Runnable {
Access1$1(Access1 access1) {
this$0 = access1;
}
public void run() {
System.out.println(3);
}
private final Access1 this$0;
}
Since the value of i is final, the compiler can "inline" it into the inner class.
As I see it, accessing local variables from method-local-classes (e.g. anonymous class) is a risky thing. It is allowed by the compiler, but it requires good understanding of what is going on.
When the inner class is instantiated, all the references to local variables it uses are copied, and passed as implicit constructor parameters (check the bytecode). Actually the compiler could have allowed making the references non-final, but it would be confusing, since it would not be clear what happens if the method alters the references after the instantiation.
However, making the reference final does not eliminate all problems. While the reference is immutable, the object behind the reference may still be mutable. Any mutations of the object done between the instantiation of the inner class until its activation will be seen by the inner class, and sometimes this is not the intention of the programmer.

Categories