From the question What's the meaning of System.out.println in Java? I found that out in System.out.println is a static field.
From C/C++ background, it's easy to understand static method, as it's the same as function in C. However, I'm not sure the use case of static field.
Is it just a way to use multiple methods without instantiating an object just as we use System.out.println without instantiating anything? Or is there any use cases for static field?
static variables/methods not only have the property of being used without instantiation, but they are also consistent across multiple instances.
For example,
public class A {
public int a = 1;
public static int b = 2;
}
Now, when I do A a1 = new A() and A a2 = new A(), A.a gets 2x the memory and is stored in the object instance, while A.b gets the memory only once and is stored outside the instance.
A prime example of this would be
a1.b = 3;
System.out.println(a2.b);
This will print 3, instead of 2, because a1 changed the value of b for the whole class, and therefore, all the instances.
A static field is a property of the class, which gets allocated on the heap and is independent of a particular object instance.
You could use a static variable to count the number of instances of a class for example.
out is an object of PrintStream.
System is a class in java.lang package
println is an instance method(not a static method) of PrintStream class
To access the field out in System without instantiating System, the field is declared static.
The System class has only one instance of the OutputStream that writes to standard output (called out) so it's a static variable. We don't need more than one instance because there's only one standard output.
A static field, is a field that is set-up and can be get without instantiating a class (using new ClassName()).
For example:
public class MyClass {
public static int number = 1;
}
With the code above, you can get the "number" field using MyClass.number.
public class MyClass {
public int number = 1;
}
Now, you need to instantiate MyClass via constructor. Since there is no constructor declared, you just use new MyClass():
MyClass cl = new MyClass();
cl.number; // <-- The number
Static fields are also known as 'class' fields (as opposed to 'instance' fields).
That means that they are accessible without you needing to instantiate the class first.
So, you can call class methods (like Math.abs() on the Math class) without having to instantiate a Math class. You can also access properties like Math.PI.
Also, changing a class property means that it affects all instances of that class, meaning that every object that was instantiated will see this value change, allowing you to affect them with a single property change.
In addition to the .out var in System, it can either be used as a shared variable that all instances of a class can update
private static int meatballsConsumed;
Or as a general-purpose shared variable
public static String thisSeemsDangerous;
Or as a constant
public static final String FLD_OF_DREAMS = "COSTNER,KEVIN";
Related
I write java code like this:
final int value=0;
When I use "Svace Static Analyzer" to anylyze the code,it shows:
This class contains an instance final field that is initalized to a compile-time static value, Consider making the field static---->
static final int value=0;
I know static value is loaded in compile time. Can anyone explain the advantage of compile load?
Scenario 1:
class Mango{
final int marker = 10;
}
In a class, when you declare a variable as final and initialize it during declaration, that means you do not want to modify it from anywhere.
In that case, all of the created objects of the class maintained a similar value for this variable.
On the other hand, whenever we declare a variable as static, then at the class level a single variable is created which is shared with the objects. Any change in that static variable reflects to the other objects operations.
But actually, at points 1 and 2 we want to achieve point 3's behavior implicitly.
So, java force or suggest you create only one copy of the marker variable by declaring is static also.
class Mango{
final static int marker = 10;
}
Which is memory efficient, cleaner, and non-ambiguous.
Scenario 2:
public class Mango {
final int marker;
Mango(int m){
marker = m;
}
}
This type of declaration is totally different. In that case, every instance of the Mango class has its own marker variable, and it can be initialized only one time.
The first type of declaration ensures class-level final behavior and the second type of declaration ensures the object-level final behavior.
I'm new to Java and is trying to learn the concept of static initialisation blocks. I saw the code and statements below from Java tutorial oracle. My question is, why did the tutorial states:
"the advantage of private static methods is that they can be reused later if you need to reinitialise the class variable"
when there is only one copy of class variable that is shared between all instance of this particular class?
class Whatever {
public static varType myVar = initializeClassVariable();
private static varType initializeClassVariable() {
// initialization code goes here
}
}
Sometimes you want to reset the static variable to its initial value.
One example could be a global counter that you want to reset from time to time
class Whatever {
private static int counter = getCountInit();
public static resetCounter() {
counter = getCountInit();
}
private static getCountInit() {
return 0; // or some fancy computation
}
}
Another example is testing: Imagine you have a test-case A that changes some static variable of a class and a test-case B that also uses the static variable. Without setting the static variable back to the initial value, the outcome of the tests would be different depending on the order in that they run.
(side note: That is one major reason why having global state (and a static variable is global state) is often a bad idea - at least in larger software projects.)
static for variable word means it is shared among all of the instances of the class so for example if you have
class SpaceShip and have static variable color = "blue";
and create alot of spaceships I mean instances of that class
and you then change color to "red"
then all spaceships will have red color ...
Static objects can be accessible only by static methods. So in case if you want to reset a static object value we should use static method for that. Generally this will not be exposed to API users so its better to keep them private here.
I want to know how many instances of a static member class can be created by the enclosing class. I assume one only, but then the following extract from Bloch doesn't make sense to me.
Quoting Joshua Bloch's Effective Java - Item 22*: Favor static member classes over nonstatic.
A common use of private static member classes is to represent components of the object represented by their enclosing class. For example, consider a Map instance, which associates keys with values. Many Map implementations have an internal Entry object for each key-value pair in the map. While each entry is associated with a map, the methods on an entry (getKey, getValue and setValue) do not need access to the map. Therefore, it would be wasteful to use a nonstatic member class to represent entries: a private static member class is best. If you accidentally omit the static modifier in the entry declaration, the map will still work, but each entry will contain a superfluous reference to the map, which wastes space and time.
He states that the map creates an Entry object for each key-value pair in the map, i.e. multiple instances of the static member class.
So my assumption is wrong! That means my understanding of static member classes is wrong. Everyone knows how a static member variable behaves, the classic static final string for instance - there is only one instance of the object.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API? Every other Collections class could then just provide it's own implementation.
[*] Just realised that it's item 18 in the PDF version of the book I have
This is a common misinterpretation of the static keyword.
When you use static with a variable it means there will be only one of these for all objects of this class or something like that.
static Object thereWillBeOnlyOne = new Object();
However, in the context of inner classes it means something completely different. A static inner class has no connection with an object of the enclosing class while a non-static inner class does.
A static inner class:
public class TrieMap<K extends CharSequence, V> extends AbstractMap<K, V> implements Map<K, V> {
private static class Entry<K extends CharSequence, V> implements Map.Entry<K, V> {
The Map.Entry class used by my TrieMap class does not need to refer to the object that created it so it can be made static to save the unnecessary reference.
A non-static inner class:
public final class StringWalker implements Iterable<Character> {
// The iteree
private final String s;
// Where to get the first character from.
private final int start;
// What to add to i (usually +/- 1).
private final int step;
// What should i be when we stop.
private final int stop;
// The Character iterator.
private final class CharacterIterator implements Iterator<Character> {
// Where I am.
private int i;
// The next character.
private Character next = null;
CharacterIterator() {
// Start at the start.
i = start;
}
public boolean hasNext() {
if (next == null) {
if (step > 0 ? i < stop : i > stop) {
next = s.charAt(i);
i += step;
}
}
return next != null;
}
The CharacterIterator inside a StringWalker object refers to the string to be iterated as s which only exists once in the StringWalker object. I can therefore create many iterators of a StringWalker and they all walk the same string.
Why this weirdness?
This seemingly illogical duality derives from the use of the static keyword in C.
In C you can (or at least used to be able to) do:
void doSomething () {
static int x = 1;
if ( x < 3 ) {
} else {
}
x += 1;
}
and each time you called the function, x would be as you left it last time around - incremented in this case.
The concept was that the static keyword indicated that the variable was scopefully enclosed by its enclosing block but semantically enclosed by its parent block. I.e. the above code was roughly equivalent to:
int x = 1;
void doSomething () {
if ( x < 3 ) {
} else {
}
x += 1;
}
but x was only allowed to be referenced inside the function.
Take that concept forward into Java and things now make a little more sense. A static inner class behaves exactly like it was declared outside the class while a non-static inner bonds much more tightly to its enclosing instance - in fact it can refer to the instance directly.
Also:
class Thing {
static Object thereWillBeOnlyOne = new Object();
behaves much like
Object thereWillBeOnlyOne = new Object();
class Thing {
if it were legal.
Here endeth the lesson.
I think the Java team messed up the naming on this one. A static inner class (strictly speaking their correct name is "static nested class") is in no way different from an ordinary class except it has a fancy name (Something.MyClass instead of MyClass) and can be made private (i.e. not instantiable from other classes).
In case of Map, it was solely chosen because the name Map.Entry makes it clear that Entry relates to Map. As you suggest, it would have been perfectly reasonable to just use an ordinary class for this. The only difference is you don't get to write Map.Entry.
I think what they should have done is to use the syntax for "non-static" inner classes (i.e. just class in an enclosing class) for static nested classes, and instead invent a new keyword to create "non-static" inner classes, because it's these that behave different from normal classes. Maybe something like attached class. AFAIK the keyword static was chosen in order to avoid having too many reserved keywords, but I think it just encouraged confusion.
Yes, you can have many instances of the nested class, no matter that the nested class is static.
When the nested class is static you can create instances of it without having an instance of the enclosing class, this is one of the benefits, and basically the main difference between static and non-static nested classes.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
It's instantiated when it's constructor is called. Not any different from non-static classes. The nested class itself is loaded by the JVM, when the code first accesses it. Again this is not any different when compared to other classes, I think (not 100% sure of this though, but you can test it yourself). So I think you're kind of mixing the terms "loading the class by the JVM" and "instantiating the class".
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API?
As said, it's easier to create instances of static nested classes. You don't need an enclosing instance which is sometimes (maybe most of the times) exactly what you want.
See also:
(1) Nested Classes
(2) How can the JVM decide if a class is nested into another class?
(3) Loading of a nested class by the JVM
You can search for other references along these lines.
The reference (2) seems advanced and kind of peripheral to your question.
what's the point of Map using a static member class for Entry?
That's because, it makes the package structure logically correct.
Why not just use an interface on the API?
Now, this is a design discussion nobody would like to be dragged into.
This question already has answers here:
What is the reason behind "non-static method cannot be referenced from a static context"? [duplicate]
(13 answers)
Closed 9 years ago.
I'm fairly new with Java and I'm having some trouble understanding what I'm doing wrong. Here is a brief description of the purpose of the program.
Make a bank account.
Deposit 1000 into it.
Withdraw 400.
Withdraw 500.
Print out results and expected results.
Here is my code. Keeps on saying non-static variable bankAcc cannot be referenced from a static context.
public class BankAccountTester
{
private double bankAcc; //Stores bankAcc balance
public void money(double deposit)
{
deposit= (1000);
int withdraw1 = -400;
int withdraw2= -500;
bankAcc= bankAcc + withdraw1 + withdraw2;
}
public double getbankAcc()//Returns value to bankAcc so it has new balance
{
return bankAcc;
}
//Prints out value and expected value
public static void main(String[] args){
System.out.Println("My bank account has " + bankAcc);
System.out.Println("Expected is 100");
}
}
main() is a static method i.e. no class instance is associated with it. While bankAcc is an instance member of BankAccountTester class and hence cannot be accessed without creating its instance first. Test your program with an object instance available as:
public static void main(String[] args){
BankAccountTester bat = new BankAccountTester();
bat.deposit(0.0);
System.out.Println("My bank account has " + bat.getbankAcc());
System.out.Println("Expected is 100");
}
Also, see here.
When you write a class, there are two "flavours" of class content. Static, which exists as global properties tied to "the class" and non-static, which lives on individual objects that you build using that class definition. As such, your code -to java- looks like this:
for objects: private double bankAcc, public void money, public double getbankAcc
for global class access: public static void main
static code exists irrespective of whether any objects have been built, so you can't tell a static method that it should access an object variable: it doesn't exist as far as it knows. Even if you do create an object from this class, it will locally have a variable called backAcc, but it's not statically accessible.
The general recipe you want to follow is this:
public class Test {
private long whatever = 123456;
public Test() {
// real code goes here.
System.out.println("my whatever variable holds " + whatever);
}
public static void main(Sting[] args) {
// build an object based on the Test class.
// and let it handle everything else.
new Test();
}
}
When you compile and run this code, the Test class will have a static (=globally callable) method main, which builds an actual Test object. Before you do, there are objects to work with, only the class definition exists. Once you build a Test object, it can then do everything you need to do, in a nice object-oriented way.
First, static (re. a variable) means that there exists one global instance of that variable for the class. This is opposed to simply private double bankAcc;, which is saying that each instance of the class has its own bankAcc.
More particularly to your problem, since main is static, it is not a method on an instance of BankAccountTester. This means that, when you are trying to print out bankAcc, you are trying to access a non-static variable from a static context, which is not allowed.
Without seeing where exactly you use money and getbankAcc, you can fix this by changing:
private double bankAcc;
to:
private static double bankAcc;
The variable bankAcc is an instance variable, meaning that it only exists when you create an instance of BankAccountTester (using new BankAccountTester()). Since you are only calling it from the static main() method without creating an instance, there is no bankAcc variable. Change the declaration to private static double bankAcc; to make your program work.
Since main is a static method, it can only refer to static variables and methods. A static variable looks like:
private static double bankAcc;
As you have it written, bankAcc is an instance variable, meaning it's tied to a specific instance of BankAccountTester.
Since you don't have any instances (i.e., you have not created a new BankAccountTester()), you can only refer to the static parts of BankAccountTester.
This is basic Java. That's why someone has voted your question down. But here's the answer.
In Java, the most common way to execute code is to reference a class that contains a main method when starting a JVM via the java command. For instance:
java com.me.MyClass
This will start a jvm and look for a main method on MyClass to execute. Note, main method is static.
On the other hand, Java classes most commonly define "classes". These are the definition of object structure. An object is a runtime instance of a class, complete with it's own memory. Your field bancAcc is an instance field, as opposed to a static field. That means each object instance of your class BankAccountTester will have it's own dedicated memory for hold a value of a bankAcc. Note, this doesn't exist unless you create an ojbect.
So, in your code, you haven't created an instance object. You could do so with the new constructor, and then reference the bankAcc on that instance object; note, there is no bankAcc unless there's an instance object. So . . .
BankAccountTester accTester = new BankAccountTester();
accTester.bankAcc = 100.00;
System.out.Println("My bank account has " + accTester.getBankAcc() );
Note, you have been confused because you have wrongly assumed that the main method's existence in your class has something to do with the class defined therein. The placement of the main here is arbitrary and unrelated to your actual class definition. To clarify it in your head, you should create two classes, one that defines the bank account, and another that is your "bootstrapper" class.
The bootstrapper will contain ONLY a main method, and it will create instances of the objects, defined by classes found in separate class files, and execute methods on them.
In the following example, the variable b is declared final, but not static. That means it's a constant instance variable. However, because it's constant, none of the Passenger objects can change its value. So isn't it better to declare it static and make it a class variable, so that there is only one copy to be used by all instantiated objects?
class Passenger {
int a;
final int b = 0;
void drive() {
System.out.println("I'm driving!");
}
}
The purpose of final but non-static variables is to have an object-wide constant. It should be initialized in the constructor:
class Passenger {
final int b;
Passenger(int b) {
this.b = b;
}
}
If you are always assigning a constant literal value (0) to the final variable, it doesn't make much sense. Using static is preferred so that you are only having a single copy of b:
static final int b = 0;
BTW I don't think having default access modifier was your intention.
It depends on the purpose of b. Usually constants are there for a specific purpose. If you make it static you could accidentally change it in some instance of that class and that will affect all the others.
If you have multiple instances of Passenger class, I would go for making it static. While this has little benefit when talking about an int variable, this could save some memory if you have complex objects. This is because a static variable belongs to a class, not to an instance, thus memory space for it will be reserved only once, and it will be referred by the class object itself, not by the instances. Of course, you should be aware that having b as a static variable means that the changes made on this variable will be reflected on all the classes that access this variable, but since you made it final this won't be the case.
Note also that with the code you've written, classes in the same package as Passenger will be able to read the b value by accessing it via Passenger.b (if static).
In java, the static attribute basically means: associated with the type itself, rather than an instance of the type.
In other words you can reference a static variable without creating instances of that type... Whereas in the case of just using final you'd need to instantiate the class.
So, yes, to answer your question, I'd say that you're right. :)
A final primitive is the same as a static final primitive (except more efficient)
A final reference to an immutable object the same as a static final reference of the same.
A final reference to a mutable object is NOT the same as a static final reference of the same.
final int i = 0;
// same as
static final int = 0;
final String hi = "Hello";
// same as
static final String hi = "Hello";
final List<String> list = new ArrayList<String>();
// is NOT the same as
static final List<String> list = new ArrayList<String>();
The only time the last example is the same is when you have a singleton. It is fairly common for singletons to be written with a confusion of static and non static fields and methods as the difference is not obvious. :|
A final variable is defined when you need a constant, so you can assign a value just once.
Using static, instead, you are defining a variable shared by all the objects of that type (like a global variable) and it is not associated with a certain object itself.