Can an instance of a class modify static / class variable? - java

class Person {
public static int age = 10;
}
public class Application {
public static void main(String[] args) {
Person p = new Person();
p.age = 100;
System.out.println(Person.age);
Person.age = 22;
System.out.println(p.age);
}
}
I got 100 and 22 printed. Was I wrong in assuming that instances of a class cannot access/modify class/static variables.

I think the part your confused by is the meaning of static. the age variable in class Person will be shared across all instances of Person, and can be accessed with no instance at all via:
Person.age = 100;
Changing it for any instance:
Person p = new Person();
p.age = 100;
changes it for everyone, and is the same as calling
Person.age = 100;
Changing it in a non static way, meaning via some instance only makes the code misleading by making people think they are changing an instance variable at first glance. You will get a compiler warning about this.

Yes, they can. From the docs:
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. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class

Of course an instance of a class can access and modify a static field, if it's accessible to that scope.
What cannot happen is a static statement/method body modifying an instance it does not "know about", e.g. a static method using this.
Example
public class Main {
private static int meh = 0;
int blah = 0;
public static void main(String[] args) {
// ugly but compiles fine
// equivalent to Main.meh = 1
meh = 1;
// Will NOT compile - main method is static,
// references instance field "blah" out of scope
// Equivalent to this.blah = 1
blah = 1;
}
}

Related

why doesn't the variable increase?

I am learning Java, so I understand this is a very simple question, but I still want to understand it.
I want to let my code automatically generate soldiers, and the number automatically increases, but I failed.
the Soldier.class:
package com.mayer;
import java.util.Random;
public class Soldier {
private int number=0;
private int ATK;
private int HP;
Random ra = new Random();
public Soldier(){
this.number++;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
public void report(){
System.out.println("number:"+this.number+"\t"+
"ATK:"+this.ATK+"\t"+
"HP:"+this.HP);
}
}
the main.class
package com.mayer;
public class Main {
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier();
i++;
}
for(Soldier sol:soldiers){
sol.report();
}
}
}
That's what I get:
number:1 ATK:94 HP:187
number:1 ATK:94 HP:181
number:1 ATK:96 HP:193
number:1 ATK:90 HP:183
number:1 ATK:95 HP:193
So you see,each of this number is 1.
You have added number field which is instance field. It will initialize per instance. You are looking for static type variable. Please check static into java.
Instance Variables (Non-Static Fields) Technically speaking, objects
store their individual states in "non-static fields", that is, fields
declared without the static keyword. Non-static fields are also known
as instance variables because their values are unique to each instance
of a class (to each object, in other words); the currentSpeed of one
bicycle is independent from the currentSpeed of another.
Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there
is exactly one copy of this variable in existence, regardless of how
many times the class has been instantiated. A field defining the
number of gears for a particular kind of bicycle could be marked as
static since conceptually the same number of gears will apply to all
instances. The code static int numGears = 6; would create such a
static field. Additionally, the keyword final could be added to
indicate that the number of gears will never change.
The constructor is changed to:
public Soldier(int number){
this.number = number;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
As others have said, each Soldier instance has its own separate number field which starts with 0. You can use a static field to count the instances:
public class Soldier {
private static int counter = 0;
private int number;
// other fields left out for clarity
public Soldier(){
Soldier.counter++; // field shared among all Soldier instances
this.number = counter; // number belongs to this instance only
// ...
}
// ...
}
However, I wouldn't recommend doing it this way. When you get more advanced, you'll learn that using a static field like this can cause problems in a multi-threaded application. I would instead advise passing the number to the Soldier constructor:
public class Soldier {
private int number;
// ...
public Soldier(int number){
this.number = number;
// ...
}
// ...
}
And then:
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier(i);
i++;
}
Soldier.class
all-uppercase field names tend to be used for constants.. basic fields use headless camel-case.. They should also be descriptive, i.e. you should look at them an it should be apparent what they represent - for example a variable "number" is not a good idea, because it's ambiguous
Random can be converted to a local variable, no need to keep it on the class level
The mechanism by which soldiers are assigned IDs should be on a higher level - it can't be managed by the soldier object itself, hence the constructor with an argument
overriding the toString method is the traditional way of transforming the object to string for debugging purposes.. also most IDEs can generate it with a press of a button so no space for human error
You will obviously need getters and setters for your variables, if you wish to read or change them from elsewhere, but I don't think that's necessary to post here.
private int soldierID;
private int attack;
private int health;
public Soldier(int id){
this.soldierID = id;
Random random = new Random();
this.attack = random.nextInt(10) + 90;
this.health = random.nextInt(20) + 180;
}
#Override
public String toString() {
return "Soldier{" +
"soldierID=" + soldierID +
", attack=" + attack +
", health=" + health +
'}';
}
Main.class
it's perfectly fine and actually preferred to use a List instead of an array, because it's more comfortable to work with
this way it's even much easier to add them dynamically and use the iterator for ID
you can "report" in the creation cycle
This even shortens the method a bit, not that it's that important here.
public static void main(String[] args){
List<Soldier> soldiers = new ArrayList<>();
for(int i=0; i<5; i++){
Soldier newSoldier = new Soldier(i);
soldiers.add(newSoldier);
System.out.println(newSoldier.toString());
}
}
This way when you define the soldier IDs it's not from within the Soldier class but rather from something that is "observing" all the soldier classes and knows which is which.

Can a Variable be initialized inside a Class in Java? What about Static Variable? If yes, then what's the use for Static Block?

In C++(prior to C-11), we needed to initialize the variables outside the Class either through constructors or some methods. What's happens in Java?
Can a Variable be initialized inside a Class in Java?
Yes, like this:
public class MyClass {
private int myVariable = 10;
}
What about Static Variable? If yes, then what's the use for Static Block?
Yes, static variables can be initialized in the class as well:
public class MyClass {
private static int myVariable = 10;
}
Static blocks are used when you want to initialize a static variable, but one line is insufficient. For example:
public class MyClass {
private static HashMap<Integer, Integer> myMap;
static {
myMap = new HashMap<>();
myMap.put(10, 20);
myMap.put(20, 40);
}
}
c++ v/s Java:
Common- both OOP language
difference- c++ is not purely object oriented language, but Java is purely oop language.
Classes are blueprint(like a general map) which defines some attributes/properties(Member variables) and behavior(member functions) of a object of that class.
Class is just a imagination before creation of a object.
Object is real time entity that has physical existence in real world or in simply it's a implementation of class.
Classes in java:
class class_name
{
member variables;
member functions;
};
Ex.
class A
{
int a;
void funct()
{
//body
}
}; //defination is closed with semicolon
but,
classes in java:
ANSWER to ur quesion:
class class_name
{
member variables; //still we define the attributes in class that may be static or non-static
member functions;
};
Significance of static variable:
static variable is alloacated the common memory in ram for all the objects of that class and operation perform by any object on static member is reflected to all other object's static member because of common(same) memory.
significance of static method(functions are called methods in java): static method of a class is a method which is called without creating the object of that class.
In java, main() method is declared as static because after execution of program main() method is called without creating the object of class.
kernal of OS calls the main() method.
Can a Variable be initialized inside a Class in Java?
Yes.
class TestClass {
int abc = 0;
static int def = 1;
}
What about Static Variable?
Yes, you can. Same Example as above.
But this won't be initialized every time an object of the class is created.
TestClass ob1 = new TestClass();
ob1.def = 2; // Always use the class name to access static variables. This is just an example.
TestClass ob2 = new TestClass();
System.out.println(ob2.def); // Output : 2
PS : Always use the class name to access static variables. This is just an example.
What's the use for Static Block?
If the initialization of static variables is complex, then you can create a static block and initialize those variables there. Here is a good reference for the same.
class TestClass {
int abc = 0;
static int def = 1;
static {
int x = 100;
int y = 20;
def = x - y + 10;
}
}
If you wat to initialize the variable you can create something like
public class Animal
{
int age = 21;
static int roll = 23;
}
But remember the difference between instance variables and static variables,
int age - this variable is created for each object you create
static int roll - this variable is created only once and is one for every other object.

Does the final keyword store variables inside methods like static?

Newbie to Java here. I'm in the process of porting my iPhone app to Android. From what I've read, the final keyword is pretty much equivalent to static. But does it work the same inside a method?
For example in Objective-C inside a method... static Class aClass = [[aClass alloc] init]; wouldn't be reallocated again and it wouldn't be disposed at the end of the method.
Would something in Java inside a method like... final Class aClass = new aClass(); act the same?
No. Block-local variables go out of scope when the block is exited and are logically (and usually physically) allocated on the stack.
Java isn't really like Objective C in that respect, and final is more akin to const because it indicates a reference may not be altered. In your example, when the block ends the final variable will be eligible for garbage-collection as it is no longer reachable. I think you want a field variable something like
static final aClass aField = new aClass();
Note that Java class names start with a capital letter by convention...
static final MyClass aField = new MyClass();
You are confusing the meaning of Final and Static.
Final means that the value of the variable cannot be changed after its value is initially declared.
Static means a variable can be accessed and changed without needing to instantiate a class beforehand.
Perhaps the following bit of code will make this more clear.
public class SF1 {
static int x;
final int y = 3;
static final int z = 5;
public static void main(String[] args) {
x = 1;
// works fine
SF1 classInstance = new SF1();
classInstance.y = 4;
// will give an error: "The final field main.y cannot be assigned"
z = 6;
// will give an error: "The final field main.z cannot be assigned"
reassignIntValue();
// x now equals 25, even if called from the main method
System.out.println(x);
}
public static void reassignIntValue() {
x = 25;
}
}
You have to declare your variable in class scope so you can able to access it outside of your method.
class ABC{
int a;
public void method(){
a = 10; // initialize your variable or do any operation you want.
}
public static void main(String args[]){
ABC abc = new ABC();
System.out.println(abc.a) // it will print a result
}
}

Static methods and static fields in Java behave somewhat in a strange way

By convention, a static method specifically in Java can have access only to static fields or other static methods. The following simple code snippet however appears to violate the convention. Let's consider the following simple code snippet in Java.
class Super
{
protected static int x;
protected static int y;
public Super(int x, int y)
{
Super.x=x;
Super.y=y;
}
public static int sum()
{
return(x+y);
}
}
final class Sub extends Super
{
public static int temp=100;
public Sub(int x, int y)
{
super(x, y);
}
public void concreateMethod()
{
System.out.println("\nInstance variable x = "+x);
System.out.println("Instance variable y = "+y);
}
}
final public class Main
{
public static void main(String[] args)
{
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
System.out.println("\nConcreate method called.");
s.concreateMethod();
}
}
The above code produces the following output with the respective statements.
Associating with object x = 10
Associating with object y = 5
Associating with class name x = 10
Associating with class name y = 5
Summation (Associating with object) = 15
Summation (Associating with class name) = 15
Associating with class name temp = 100
Associating with object temp = = 100
Concreate method called.
Instance variable x = 10
Instance variable y = 5
The static fields s and x are being accessed through the following statements within the main() method using the object of the Sub class, though they are declared as static in the super class Super.
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
The following statements of course, have no doubt.
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
Since x and y are static, they can certainly be accessed in this way.
The same is the method call, observe the following statements.
Sub s=new Sub(10, 5);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
Both of the ways, the static method sum() is being accessed using the object of the class Super and also using the class name Sub.
Again the similar case with the static field temp declared within the Sub class
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
The static field temp is being accessed in both the ways.
Why is this happening here?
Basically it's a flaw in the design of Java IMO which allows static members (methods and fields) to be referenced as if they were instance members. This can be very confusing in code like this:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
That looks like it's sending the new thread to sleep, but it actually compiles down into code like this:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
because sleep is a static method which only ever makes the current thread sleep.
Indeed, the variable isn't even checked for non-nullity (any more; it used to be, I believe):
Thread t = null;
t.sleep(1000);
Some IDEs can be configured to issue a warning or error for code like this - you shouldn't do it, as it hurts readability. (This is one of the flaws which was corrected by C#...)
There is no problem there. Static methods can only access static fields and call other static methods as you have stated. Nothing in your examples does otherwise.
Non-static methods can access both static and non-static methods and fields. Again, none of your examples violate that.
The Sub.temp and s.temp are equivalent and you can use both, it means the same. But 1st is better one because suggests it's a static field.
a static method specifically in Java can have access only to static fields or other static methods declared within the same class
Or its superclass.
I don't see any violation here, you can access static fields/methods via its concrete object or class name. both refer to the same thing.
Where do you see a non-static field or method being accessed by static code? Everything seems perfectly fine to me.
Perhaps what's confusing you is that static fields and methods can be accessed through instances as well as through the class name? It's certainly a big ugly and many consider it bad design, but that's all.

When making a class to hold variables should the variables always be static?

Say I wanted to make a class to hold a set of integers that would be accessed from multiple other classes and instances. I don't want them reverting to the value they had when the code was compiled. Does that mean they have to be static, in order to keep them from going back their original value? For example
The original stats holding class here:
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
It is called on in two places. Here:
public class exampleClass() {
private Stats stats = new Stats();
stats.numOne += 5;
//More variable changes.
}
Also here:
public class exampleClassTwo() {
private Stats stats = new Stats();
stats.numOne -= 3;
//More variable changes.
}
Will these calls reset the variables to their original class value if the variables are not static? If so, does that mean they should always be static?
No, the variables will maintain state without the static modifier
No. You would use static key word for using those values without initializating them.
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
public class exampleClass() {
int a = 0;
a += Stats.numThree;
System.out.println(a);
}
>>> 3;
No need for static attributes in your case indeed, each class instance will contain a private copy of attributes initialized at instance creation time, and records all subsequent modifications until object is deleted (in java it means no longer referenced).
Main usage for static is either to store constants or global state (e.g. a singleton instance).
Doing,
private Stats stats = new Stats();
stats.numOne += 5;
Kind of defeats the purpose of having numOne as static.
The static field numOne should be accessed in a static way i.e as follows: Stats.numOne
static variables are Class variables and are used when we want to maintain a value across instances of the class. So modifying the value of numOne across various functions will keep on changing the value of class variable numOne. Run the following code to see the effect of having a class variable in a class:
public class StaticVarDemo {
public static int staticCount =0 ;
public StaticVarDemo(){
staticCount++;
}
public static void main(String[] args) {
new StaticVarDemo();
StaticVarDemo.staticCount +=5;
System.out.println("staticCount : " + StaticVarDemo.staticCount);
new StaticVarDemo();
new StaticVarDemo();
System.out.println("staticCount : "+staticCount);
}
}
It will give the output:
staticCount : 6
staticCount : 8
Yes, when you instantiate an object, variables will be initialized to the class values when they are not static.
When a variable has the static keyword, that variable value persists over all instances: the two places you called it each create an object, both objects have the same values for their static variables (even if they are changed).
Variables without the static keyword are unique to the instance: changing it on one object doesn't affect its value on the other.
See here for more info:
What does the 'static' keyword do in a class?
It seems after some research a singleton did the job. Creating one singular instance but calling on it more then once.
See Here:
http://www.tutorialspoint.com/java/java_using_singleton.htm

Categories