Java Static confusion - java

I'm working with Java; I have worked with C++ before. I am thinking about static usage in Java. If I create static methods and variables in the class, Why can I access them through the object also?
Example:
class Test{
static int count=0;
int id;
static void updatec(){
count++
}
}
class TestMain
{
public static void main(String args[])
{
Test.count=1;
Test t = new Test();
t.count=5; // Valid WHY ?????
}
}
Why this is allowed? Java's site says we should not use obj.static method/variable.
Why it is allowed?

Static doesn't mean that the field is only for the class. It means it for the class and all its instances.
In this example, the class variable origin of the class Point is referenced both using the class name as a qualifier, in Point.origin, and using variables of the class type in field access expressions (§15.11), as in p.origin and q.origin. These two ways of accessing the origin class variable access the same object, evidenced by the fact that the value of the reference equality expression (§15.21.3):
q.origin==Point.origin is true
But you're right it's usually a bad idea to refer to a static field/method/class from a non-static context, it can confuse the developer.
Resources :
JLS - static Fields

It's legal to access static fields through an instance, although you'll generally get a warning about it. The field is still static, however, so there's only one per class:
Test t = new Test();
Test u = new Test();
t.count = 5;
System.out.println(u.count); // Outputs 5

There is no good reason why this is allowed. It's confusing and it serves no purpose. Good tools will warn you about this (or maybe even give you the option to fail compilations over it). But it is part of the language and so it will never be taken out because that would break existing code.

It really should not have been supported. This support leads to this dubious code in org.apache.commons.cli command-line parser.
class OptionBuilder
public static Option create();
public static OptionBuilder withLongOpt(String newLongopt);
public static OptionBuilder withDescription(String newDescription);
This leads to this:
Option opt =
OptionBuilder
.withLongOpt( "opt" )
.withDescription( "opt description" )
.create( );
It would be much better and cleaner and thread-safe, if there were a default OptionBuilder constructor and all static methods were instance methods. That's the model used by StringBuilder/StringBuffer

Your snippet is perfectly legit, either in Java or C++ equivalent.
It seems you're confusing access restriction (private, protected, public) and instance/class distinction for members (static keyword).
Since you have an instance of class Test (named t) in your static main method, you can use instance methods/members of class Test, that's conforming with the documentation you quoted.
If the count field was private or protected, you wouldn't be able to access it, but that would have nothing to do with static.

You shouldn't doesn't mean you can't.
Anyway, this is allowed in C++ also.

static in this case means there's one shared instance per class, not per instance. So when you change t.count, you're changing the 'count' member for the whole class and ALL instances.
That is, these will print the same value:
System.out.println(t.count);
System.out.println(Test.count);
There's nothing illegal about it, although it's usually not a great idea because it looks like instance data.

Related

JAVA: difference between Static method invocation with className and with Object of instance

I'm little confused on the calling static methods, any way i know this kind of rule
Foo.staticMethod(); //accessing static method.
for non-static method we must instantiate the class.
Foo person1 = new Foo(); //instantiating
person1.nonStaticMethod(); //accessing non-static method.
so all we know that static methods are known among the class so does not give a sens when we call it within the object reference like in Doc Oracle
its say :
Note: You can also refer to static methods with an object reference like
instanceName.methodName(args)
but this is discouraged because it does not make it clear that they are class methods.
Finally my question is as below:
public class Foo{
static int x = 10;
public static void method(){
System.out.println("ANYTHING TO SHOW !!!!");
}
public static void main(String[] args) {
Foo object = new Foo();
object.method(); // ANYTHING TO SHOW !!!!
Foo.method(); // ANYTHING TO SHOW !!!!
System.out.println(object.x); // Will display as result 10
System.out.println(Foo.x); //Also this will display as result 10
}
}
So why the documentation montioned that static field/method not longer with object ref while is give the same.
Note :
I know the uses of static keyword, that give smooth ref into memory which each variable declared once into the memory while is
attached to static keyword, also i know very well that static keyword
useful for hiding method from overriding when we deal with inheritance.
so these not included into my question.
By convention...
If one sees object.method(), they assume that method() is an instance method and requires an instance of Foo to be used.
If one sees Foo.method(), they know that method() is a static method and does not require an instance of Foo to be used.
This is a code readability issue more than a functional issue, since you demonstrate correctly that the code will work in either scenario. However, it does make understanding that code harder, since now the developer has to be wary of any other possible use of a static method in that fashion.
Remember: static methods don't require an instance for a reason. If you find yourself needing an instance for the method at all, it may be worth reconsidering its design.
Because the local variable x is static. If it were private, Foo.x wouldn't work and would return an error. Static methods, variables, etc. can be called by using ClassName.staticThing or by instance.staticThing. Since the variable x was static, it was able to be called by both object.x and Foo.x. If x were to be a private variable, Foo.x wouldn't work.

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)

JAVA : Accessing static method properly

I am new to JAVA, and I like to try and understand everything.
When accessing a static method "hero.returnHp()" in JAVA, I have the following:
hero Mike = new hero();
Mike.returnHp();
The program runs fine, but I notice that Eclipse has a warning stating, "The static method from the type hero should be accessed in a static way." When I accept the auto-fix, it changes "Mike.returnHp();" to "hero.returnHp();".
So I have two questions:
1) What is the advantage of this?
2) If I created two objects of the same type, how would I specify which one to return when accessing in a static way?
Thanks!
I would first like to point out what the keyword static means.
Static variables only exist once per class – that is, if you create a class with a static variable then all instances of that class will share that one variable. Furthermore, if it’s a public static variable, then anyone can access the variable without having to first create an instance of that class – they just call Hero.staticVariableName;
Static method/functions are stateless. That is, they act only on information (1) provided by arguments passed to the method/function, or (2) in static variables (named above), or (3) that is hard-coded into the method/function (e.g. you create a static function to return “hello” – then “hello” is hard-coded into the function).
The reason why Eclipse wants you to access static methods in a static way is because it lets you and subsequent programmers see that the method you’re accessing is static (this helps to prevent mistakes). The function will run either way you do it, but the correct way to do it is to access static functions in a static way. Remember that if you call a static method, no matter what instance variable you call it from (Tim.returnHp, Jim.returnHp, Mike.returnHp, whatever) you will call the same function from the hero class and you will see the exact same behavior no matter who you call it from.
If you created two objects of the same type then you COULD NOT specify which one to return when accessing in a static way; static functions/methods will refer to the entire Hero class.
Can you explain what you’re trying to do so that we can offer more specific feedback? It’s quite possible that returnHp() shouldn’t be static.
Is that “return hit points”? If it is, then you do NOT want it static because the number of hit points that a hero has is part of the hero’s state, and static methods are stateless. (Think of state like the current condition – alive, dead, wounded, attacking, defending, some combination of the aforementioned, etc.) I would recommend going into the Hero class and changing returnHp to a non-static method.
Now… I know you didn’t ask, but I would like to advise you of something:
Class names (such as Hero) should be capitalized. Instance variable names (such as mike) should be lowercase. This is a widely accepted naming convention and it will increase the readability of your code.
Jeff
A static method is one which belongs to a class but not to an object. In your example above, you have created an object Mike of class hero. The method returnHp() is static, and belongs to the hero class, not the hero objects (such as Mike).
You will likely get an IDE or compiler warning when you reference a static method from an object, because it should never be tied to that object, only to its class.
Based on the method name, I would guess it shouldn't be static.
class hero {
private float hp;
public float returnHp() { // Should NOT be "public static float ..."
return hp;
}
}
The JavaDocs on class members has a brief discussion on statics as well. You may want to check that out.
A static method is completely independent of any instances of the class.
Consider that this works, and does not result in a NullPointerException:
hero Mike = null;
Mike.returnHp();
(by the way, class names should start with a capital, and variable names be lowercased).
Here is another neat example: Being a static method, Thread.sleep always sleeps the current thread, even if you try to call it on another thread instance.
The static method should be called by class name, not through an instance, because otherwise it is very confusing, mostly because there is no dynamic dispatch as static methods cannot be overridden in subclasses:
hero Tim = new superhero(); // superhero extends hero
Tim.returnHp(); // still calls the method in hero, not in superhero
You are getting a compiler warning now, but many people say that this was a design mistake and should be an error.
It is part of the JVM spec.
You don't need to. A static method is common between instances of a class, your confusion arises from thinking it is an instance method.
static means a static way. One reason to use static is you can access it using class directly. that is its benefit. that is why main is always static. The entrance function don't need to create an instance first.
Actually if you search static in google, and understand it deeply. U will know when and why use static.

How to modify private static variable through setter method

I have the following variable in a class named Example:
private static int number;
If I wanted to assign the variable a number using an outside class, which would I do?
1) Make the setter method in Example static so I can access it like this:
Example.setNumber(3);
2) or Make the setter method non-static so I create an object of Example to set the number
Example e = new Example()
e.setNumber(3);
What are the differences between the two and which one is the better way?
It is recommendable to use a static method in this case.
Why? Well, if you make it a non-static method, that would lead to the following suprising effect:
Example e1 = new Example();
Example e2 = new Example();
e2.setNumber(3);
e1.setNumber(5);
System.out.println(e2.getNumber()); // surprise! prints 5,
So even though you called the method on e1, e2 is also affected. The corresponding static example is much less surprising:
Example e1 = new Example();
Example e2 = new Example();
Example.setNumber(5);
System.out.println(Example.getNumber()); // prints 5, no surprise...
First of all, you really shouldn't be setting static variables. It's prone to cause problems, and it's generally indicative of bad design. The only times static variables should be used are for thread-safe immutable objects and singletons.
That said, if you absolutely still want to set the value, make it a static method, ince you shouldn't need to instantiate the object in order to set a static value.
The first one would be the correct one. When you access a static method, you use the class name and not an object refrence
If it's a static variable, make the setter static. Having to create an instance just to modify something that belongs to the whole class is both verbose and wasteful.
Please don't use the second option. Creating an instance just for an assignment is a crime:P.
Use the first option or just make the number public, depending on your needs.
The setter of a static variable that do not depends on any instance variables/functions should be also static. So 1).
But beware of creating global variables!
There is no point to creating an instance of a class just to set a static variable on it. I would go with #1. (Although I try to avoid global variables, which is what the static variable is.)
Static member is the same for all instances of class. You can change is either using static or regular setter. But regular setter in this case may confuse user: the naming convention says that setter changes value of field that belongs to specific instance. Therefore you should use the first version: Example.setNumber(3).
Static variables are made static because they are not associated with any particular object.
Both approaches work, but the former is more sensible, because it does not require an arbitrary object to be created and used.
The consensus of other posters is for #1 static method.
I will argue that we can not answer the question with available information. If for example, the setNumber method is necessary to implement an interface then it should be #2 instance method. Tell us where the setNumber method will be used.

Categories