According to Java Concurrency in Practice book:
Informally, an object's state is its data, stored in state variables such as instance or static fields.
As far as I understand from Java concepts or in general, state / instance variables define the object state. As far as I know, the static fields belong to class variables. In what case does static fields define object's state?
It sounds a bit ambiguous to me - one could probably argue that static variables are inherently object state that is the same for all objects of a given type.
Personally, however I don't think that static variables constitute object state. This quote from the Oracle Java tutorial seems to support my understanding.
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. Any object can change the value of a
class variable, but class variables can also be manipulated without
creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects
and assign each a serial number, beginning with 1 for the first
object. This ID number is unique to each object and is therefore an
instance variable. At the same time, you need a field to keep track of
how many Bicycle objects have been created so that you know what ID to
assign to the next one. Such a field is not related to any individual
object, but to the class as a whole.
With that said, static variables can keep track of the status of the overall application state, which is what another question based on the same books speaks to: Object's state in public static fields
From Wiki
In object-oriented programming, there is also the concept of a static
member variable, which is a "class variable" of a statically defined
class, i.e., a member variable of a given class which is shared across
all instances (objects), and is accessible as a member variable of
these objects
Since static variable in class is shared across all the instances (objects) of class, it plays a role directly or indirectly in state of that object.
Related
I have a question about local and member variables in Java. The situation is: Sometimes if I define a local variable, that variable has to be passed around into several levels of method calls. I often think, why should I just define a member variable for the class so that the variable is available everywhere in the class. A member variable of a class is like a global variable accessible everywhere in the class.
What's the best practice for this scenario? OR what's the right thing to do?
If I define it as a member variable, should it be a static or non-static variable?
Member variables hold characteristics -- attributes is another term -- for the 'thing' in your program represented by the class. If your variable holds something like that, make it a member variable; if it doesn't, don't.
Static variables hold characteristics of the class itself, as opposed to characteristics of objects of that class.
Don't make the decision based on whether you "pass ... into several levels of method calls.
Thinking about your general question, I came up with these guidelines from my experience:
Use the smallest poosible scope. If a local variable is fine, then why use a member variable?
Model the class according to the domain. If you have a value and it is part of the class responsibility, then modeling it as a class member seems to be appropiate.
To your second question: I do generally define static variables as final which make them constants. Non-final static members in a multi-threaded environment may easily introduce race conditions. It is easier to make access to non-static member thread-safe if needed.
It's behavioral. If your variable is part of your class attribute i.e. characterizes the class behavior then define it as the class member variable otherwise define a local variable inside the method.
In my opinion, passing the argument doesn't contribute in the attribute type definition.
It depends.
If you want all (or several), of your methods to access the same member variable, then declare it in the class.
Static or not depends on wether that information belongs to the Class (static), or to an instance of the class (non-static).
1.) If you are going to use it in multiple methods and need to pass it around make its member variable. If it is just for that method make it local.
2.) static means their is only one instance of that variable that is shared among everything. So for example I have a totalGameScore variable that will keep my score for the whole game no matter what. You'd want to make that variable static. Other than that lets say I have a health variable for my enemy. Each enemy will have its own health so I would NOT make that variable static.
You can also declare member variables private so that other classes cannot access them.
Constants should normally always be member variables.
If you decide to declare a member variable then you should consider the variables scope. If you are just reducing the number of parameters on internal method calls I would consider declaring the variable as private.
You should be careful of using Static because every instance of the class will use the same copy of the variable.
I've got a Java worker that handles a lot of data. It waits on a Redis queue in main() and then calls different functions to handle the data depending on type.
I've got two questions on optimizing the code:
Would it be better to have private static class variables and use them to send data to methods instead of using function arguments?
Would it speed up execution time if variables used in these often-called methods would be private static on class instead of declared always over again when entering the method?
Thanks
You are talking about speed, but static variables will help you mostly memory-wise.
If you are creating multiple instante variables (non-static fields) and thinking of changing to into a static one:
When multiple instances of a class need access to a particular object in a variable local to those instances (instance variable), it is better to make that variable a static variable rather than have each instance hold a separate reference. This reduces the space taken by each object (one less instance variable) and can also reduce the number of objects created if each instance creates a separate object to populate that instance variable. (Quoted from Java Performance Tuning book.)
If you are not creating instance variables, but just passing a variable along in parameters:
Performance-wise, there should be no difference. As a all method parameters in Java are passed value-by-reference, meaning that the actual variable is not copied over an over: only its address (pointer - a reference to the variable) is copied into the parameter of the called method.
In any case, static fields can compromise your code's readability (it can make them so much harder to maintain). If you really need a static behaviour, please also consider using a Singleton design pattern.
Bottom line is:
Seems to me your scenario is: You are just passing variables along (an not having instance variables).
I advise you to keep it that way. If you change it, there will be near-zero (if any) performance gain by using static fields -- on the other hand, your code will be much harder to maintain/understand/debug.
In a process of leaning java serialization concept, i was puzzled at one point. In java serialization process, we use 2 keywords to prevent serialization, i.e.., transient and static. If i don't want to save an instance variable, which keyword should i use, both does exactly the same.
Class A implements Serializable{
private static int x;
private transient int y;
private transient static int x;
}
In the above code all the three instance variables are not saved in a process of serialization. Which keyword is apt and recommended to prevent serialization. Why does two keywords have almost the same functionality. What is the recommended way of declaration to prevent serialization. Correct me if I'm wrong, I'm still learning.
The static keyword transforms an instance variable into a static variable. A side-effect is that the field is not serialized anymore... because it's not a field anymore.
A static variable is a variable of the class. An instance variable is a variable of the object, or instance of the class. You can't blindly go from one to the other.
Read the tutorial page about instance and static variables.
The transient keyword is the right keyword to use, of course.
You are confused: static fields are not instance variables, they are class-wide variables. By declaring a field static, the same field is shared among all instances of this class - it is not part of any specific object anymore, which leads to it not being serialized.
To specifically prevent serialization only transient is applicable...
Transient (and in JAXB XmlTransient) signify that the data is ephemeral and not of permanent importance and thus should just be ignored when it comes to matters of persistence.
Static means the value applies that the class level and thus serializing/deserializing it for multiple instances would be unsafe as values would collide.
Well, Let me define serialization once more.
A serialization is a process in which we persist state of an object.
So, is any static variable is part of an object's state ?..No absolutely not. It is the data which is shared among all objects of a class. So obviously, any static variable is not supposed to be serialized with object's state.
let's assume, we are allowed to persist an object's state. later on, if this variable is changed by some other object/class itself, and if we try to de-serialize the object then what value this static variable will hold. There will be a clash.
So if you want to prevent any instance variable from being serialized , do use transient.
when you will de-serialize the object it will be initialized with a default value.
I'm adapting a simulation written in Java. My limited background is all in C++.
The current implementation of the simulation relies on a class called Parameters. An instance of class Simulation references attributes of Parameters, which I don't think is ever instantiated. The Parameters class has a structure like
public class Parameters {
public static int day = 0;
public static final int endDay = 365;
....
public static int getDate() {
return day;
}
}
In an instance of Simulation, there are references to, e.g., Parameters.day.
Currently, all the attributes of Parameters are hard-coded. I need to be able to change some of them with command-line arguments. For example, I'd like to be able to set a different endDay using a Parameters::setEndDay(int customDay) sort of function.
My first thought was to create an instance (Parameters parameters = new Parameters()) and completely rewrite the Parameters class so that all its attributes are private and only accessible through accessor functions. I'm concerned that this approach is not very efficient. Thus far, I have tried a hybrid approach in which I create an instance of the Parameters class, which I then pass to an instance of Simulation while still occasionally referencing Parameters.day (something I don't need to change).
One of the problems is that I don't have a good sense of class privileges in Java.
Suggestions appreciated.
If you make all of them non-final, then you can just set them directly from your command-line arguments before instantiating the Simulation class:
// read command-line arguments
Parameters.endDay = 123; // this will change all reference to Parameters.endDay
new Simulation(...)
create static method setEndDay(int customDay) in Parameters class. And you can change value without accesing with class not object: Parameter.setEndDay(10). Note that endDay variable should be non final.
Accessing static member variables vs instantiating an object
Essentially this is a choice between global data or local data. A class variable (keyword static) exist in one place for your entire application. E.g. you cannot have two parametrizations running simultaneously in the same application (although you can run two applications in parallell or sequentially). Using instantiated objects you can have several Parameter objects containing different values.
Accessor methods vs accessible member variables
There are some controversy around this. Schoolbooks usually state that all data should be encapsulated using accessor methods to protect the objects internal state. It is however as you state slightly less efficient and there are cases where making member variables directly accessible is considered good practice.
Java Access Modifiers
Java supports four different access modifiers for methods and member variables.
Private. Only accessible from within the class itself.
Protected. Can be accessed from the same package and a subclass existing in any package.
Default (no keyword). Only accessible by classes from the same package.
Public. Accessible from all classes.
What happens if i'll try to serialize an attribute which is static?
thanks
From this article:
Tip 1: Handling Static Variables
Java classes often hold some
globally relevant value in a static
class variable. We won't enter into
the long history of the debate over
the propriety of global variables -
let's just say that programmers
continue to find them useful and the
alternatives suggested by purists
aren't always practical.
For static variables that are
initialized when declared,
serialization doesn't present any
special problems. The first time the
class is used, the variable in
question will be set to the correct
value.
Some statics can't be initialized this
way. They may, for instance, be set by
a human during the running time of the
program. Let's say we have a static
variable that turns on debugging
output in a class. This variable can
be set on a server by sending it some
message, perhaps from a monitor
program. We'll also imagine that when
the server gets this message, the
operator wants debugging turned on in
all subsequent uses of the class in
the clients that are connected to that
server.
The programmer is now faced with a
difficulty. When the class in question
arrives at the client, the static
variable's value doesn't come with it.
However, it contains the default
static state that's set when the
class's no-argument constructor is
called by writeObject(). How can the
client programs receive the new
correct value?
The programmer could create another
message type and transmit that to the
client; however, this requires a
proliferation of message types,
marring the simplicity that the use of
serialization can achieve in
messaging. The solution we've come up
with is for the class that needs the
static transmitted to include a
"static transporter" inner class. This
class knows about all the static
variables in its outer class that must
be set. It contains a member variable
for each static variable that must be
serialized. StaticTransporter copies
the statics into its member variables
in the writeObject() method of the
class. The readObject() method
"unwraps" this bundle and transmits
the server's settings for the static
variables to the client. Since it's an
inner class, it'll be able to write to
the outer class's static variables,
regardless of the level of privacy
with which they were declared.
And from another article:
Static or transient data
However, this "ease" is not true in
all cases. As we shall see,
serialization is not so easily applied
to classes with static or transient
data members. Only data associated
with a specific instance of a class is
serialized, therefore static data,
that is, data associated with a class
as opposed to an instance, is not
serialized automatically. To serialize
data stored in a static variable one
must provide class-specific
serialization.
Similarly, some classes may define
data members to use as scratch
variables. Serializing these data
members may be unnecessary. Some
examples of transient data include
runtime statistics or hash table
mapping references. These data should
be marked with the transient modifier
to avoid serialization. Transient, by
definition, is used to designate data
members that the programmer does not
want or need to be serialized. See
Java in a Nutshell, page 174: mouse
position, preferred size, file handles
(machine specific (native code)).
When writing code if something is
declared transient, then this triggers
(to programmer) necessity of the
posibility of special code for
serialization later.
To serialize an object, you create
some sort of OutputStream object and
then wrap it inside an
ObjectOutputStream object. At this
point you only need to call
writeObject() and your object is
magically serialized and sent to the
OutputStream. To reverse the process,
you wrap an InputStream inside an
ObjectInputStream and call
readObject(). What comes back is, as
usual, a handle to an upcast Object,
so you must downcast to set things
straight. If you need to dynamically
query the type of the object, you can
use the getClass method. Specifically
dk.getClass.getName() returns the name
of the class that dk is an instance
of. I.e., this asks the object for the
name of its corresponding class
object. (Hmmm, True, but what about
syntax? I still need to know what it
is to declare it...too bad) (C++ can
do this in one operation (dynamic_cast
(gives null if wrong type)), java can
use instanceof operator to check if it
is what I think (see Core Java, Ch5
Inheritence, Casting section)
Yes, we can defnitely serialise the static variable, but we wont be able to get any purpose of serialisation on the static variables.
Why because the Static variables are not bounded to any objects in scope.
We serialize objects to store them so they can retrieved later for any use.
Only the Transient varibles you cant make them to get serialised.
You can serialize the value of a static variable / attribute. But strictly speaking, you don't serialize a variable or attribute in its own right, whether it is class level, instance level, or local to a method.
Normally the instance level attributes of an object are serialized as part of the parent object; i.e. the object that they are attributes of. If you translate that to class level attributes, then the notional parent is the class. While there is a runtime object that denotes this class (i.e. the java.lang.Class returned by this.getClass()), this object is not serializable. So from that perspective, a class level (static) attribute is not serializable.