How and where should we use a Static modifier for:
1. Field and
2. Method?
For example in java.lang.Math class, the fields methods like abs(), atan(), cos() etc are static, i.e. they can be accessed as: Math.abs()
But why is it a good practice?
Say, I don't keep it static and create an object of the class and access it, which anyways I can, I will just get a warning that, you are trying to access a static method in a non static way (as pointed out by #duffymo, not in case of Math class).
UPDATE 1:
So, utility method, should be static, i.e. whose work is only dependent on the method parameters. So, for example, can the method updateString(String inputQuery, String highlightDoc) should have been a static method in this question?
You can think of a 'static' method or field as if it were declared outside the class definition. In other words
There is only one 'copy' of a static field/method.
Static fields/methods cannot access non-static fields/methods.
There are several instances where you would want to make something static.
The canonical example for a field is to make a static integer field which keeps a count across all instances (objects) of a class. Additionally, singleton objects, for example, also typically employ the static modifier.
Similarly, static methods can be used to perform 'utility' jobs for which all the required dependencies are passed in as parameters to the method - you cannot reference the 'this' keyword inside of a static method.
In C#, you can also have static classes which, as you might guess, contain only static members:
public static class MyContainer
{
private static int _myStatic;
public static void PrintMe(string someString)
{
Console.Out.WriteLine(someString);
_myStatic++;
}
public static int PrintedInstances()
{
return _myStatic;
}
}
Static uses less memory since it exists only once per Classloader.
To have methods static may save some time, beacuse you do not have to create an object first so you can call a function. You can/should use static methods when they stand pretty much on their own (ie. Math.abs(X) - there really is no object the function needs.) Basically its a convenience thing (at least as far as I see it - others might and will disagree :P)
Static fields should really be used with caution. There are quite a few patterns that need static fields... but the basics first:
a static field exists only once. So if you have a simple class (kinda pseudocode):
class Simple {
static int a;
int b;
}
and now you make objects with:
Simple myA = new Simple();
Simple myB = new Simple();
myA.a = 1;
myA.b = 2;
myB.a = 3;
myB.b = 4;
System.out.println(myA.a + myA.b + myB.a + myB.b);
you will get 3234 - because by setting myB.a you actually overwrite myA.a as well because a is static. It exists in one place in memory.
You normally want to avoid this because really weird things might happen. But if you google for example for Factory Pattern you will see that there are actually quite useful uses for this behaviour.
Hope that clears it up a little.
Try taking a look at this post, it also gives some examples of when to and when not to use static and final modifiers.
Most of the posts above are similar, but this post might offer some other insight. When to use Static Modifiers
Usually when the method only depends on the function parameters and not on the internal state of the object it's a static method (with singletone being the only exception). I can't imagine where static fields are really used (they're the same as global variables which should be avoided).
Like in your example the math functions only depend on the parameters.
For a field you should keep it static if you want all instances of a given class to have access to its value. For example if I have
public static int age = 25;
Then any instance of the class can get or set the value of age with all pointing to the same value. If you do make something static you run the risk of having two instances overwriting each others values and possibly causing problems.
The reason to create static methods is mostly for utility function where all the required data for the method is passed in and you do not want to take the over head of creating an instance of the class each time you want to call the method.
You can't instantiate an instance of java.lang.Math; there isn't a public constructor.
Try it:
public class MathTest
{
public static void main(String [] args)
{
Math math = new Math();
System.out.println("math.sqrt(2) = " + math.sqrt(2));
}
}
Here's what you'll get:
C:\Documents and Settings\Michael\My Documents\MathTest.java:5: Math() has private access in java.lang.Math
Math math = new Math();
^
1 error
Tool completed with exit code 1
class StaticModifier
{
{
System.out.println("Within init block");//third
}
public StaticModifier()
{
System.out.println("Within Constructor");//fourth
}
public static void main(String arr[])
{
System.out.println("Within Main:");//second
//StaticModifier obj=new StaticModifier();
}
static
{
System.out.print("Within static block");//first
}
}
Related
can you explain me which is the difference between:
public class Test {
public static final Person p;
static {
p = new Person();
p.setName("Josh");
}
}
and
public class Test {
public static final Person p = initPerson();
private static Person initPerson() {
Person p = new Person();
p.setName("Josh");
return p;
}
}
I have always used the second one, but is there any difference with an static initializer block?
There are of course technical differences (you could invoke the static method multiple times within your class if you wanted, you could invoke it via reflection, etc) but, assuming you don't do any of that trickery, you're right -- the two approaches are effectively identical.
I also prefer the method-based approach, since it gives a nice name to the block of code. But it's almost entirely a stylistic approach.
As Marko points out, the method-based approach also serves to separate the two concerns of creating the Person, and assigning it to the static variable. With the static block, those two things are combined, which can hurt readability if the block is non-trivial. But with the method approach, the method is responsible solely for creating the object, and the static variable's initializion is responsible solely for taking that method's result and assigning it to the variable.
Taking this a bit further: if I have two static fields, and one depends on the other, then I'll declare two methods, and have the second method take the first variable as an explicit argument. I like to keep my static initialization methods entirely free of state, which makes it much easier to reason about which one should happen when (and what variables it assumes have already been created).
So, something like:
public class Test {
public static final Person p = initPerson();
public static final String pAddress = lookupAddress(p);
/* implementations of initPerson and lookupAddress omitted */
}
It's very clear from looking at that, that (a) you don't need pAddress to initialize p, and (b) you do need p to initialize lookupAddress. In fact, the compiler would give you a compilation error ("illegal forward reference") if you tried them in reverse order and your static fields were non-final:
public static String pAddress = lookupAddress(p); // ERROR
public static Person p = initPerson();
You would lose that clarity and safety with static blocks. This compiles just fine:
static {
pAddress = p.findAddressSomehow();
p = new Person();
}
... but it'll fail at run time, since at p.findAddressSomehow(), p has its default value of null.
A static method (second example) is executed every time you call it. A static init block (first example) is only called once on initializing the class.
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.
This does not count for final instances, because a final variable can only be initialized once.
initPerson requires calling at some point, whereas the static block is executed when creating the Test object.
The static before a function specifies that you can use that function by calling it on the Class name handle itself. For example, if you want to create a Person object outside the class you can write
Person p = Test.initPerson();
However, there is no advantageous difference between the two as you can access the object p outside the class in both cases.
I don't understand why methods on arrays, in Java, have to be static. Static methods can only be used on static variables right? So this would mean arrays are static variables, variables shared by a class? But what class would this be?
Can someone help me understand this?
Edit: to be more specific, I am creating methods to act on arrays but if I just write "public int[] expandArr(int[]a, int v)" and I try to use this method in the main method, I get an error saying I can't make a static reference to a non-static method. When I write "public static int[] expandArr(int[]a, int v)" it works then.
I understand you cannot change the size of an array, the method I wrote makes a new array with increased size and copies the first one into it.
Thank you.
You say you tried to write this:
public int[] expandArr(int[]a, int v)
The thing is, you had to write it in some class, since you can't just have free-floating methods in your program. Therefore, it must operate on a instance of the class. For example:
public class MyProgram {
public int[] expandArr(int[]a, int v) { ... }
public static void main(String[] args) { ... }
}
expandArr requires an instance of MyProgram, since you didn't declare it to be static. And that has nothing to do with arrays. It would be the same if you wrote
public class MyProgram {
public String expandString(String s, int v) { ... }
public static void main(String[] args) {
String s = expandString(args[0], 1); // ILLEGAL
String s2 = args[0].expandString(1); // ILLEGAL
}
}
Although the first parameter of expandString is a String, this actually operates on a MyProgram, and you cannot use expandString without an instance of MyProgram to operate on. Making it static means that you can (the first use of expandString in my example would become legal.)
In general, you can't add methods to a class without modifying the source of that class. If you want to write a new method that does something with objects of a certain class C, and you can't modify class C (perhaps because it's in the Java library or someone else's library), then you'll need to put the method in some other class C2, and most of the time you will need to make the method static since it doesn't involve objects of class C2.
You can't call a non-static method from a static method unless you first instantiate the an object of the class.
e.g.
In class Whatever...
public boolean ok() {
return true;
}
public static void main(String[] args) {
Whatever w = new Whatever();
System.out.println(w.ok());
}
You cant call a non static method from a static context. A static method belongs to the class, non static or instance methods are copied to each instance of the class (they each have their own). If I have 10 instances of class A, and class A has a static method, which all of them share, then I try to invoke a non static method in class A from class A's static method, which instance of class A gets its method invoked? The behavior is undefined.
The question really has nothing to do with arrays.
This question is related: Can't call non static method
I think what you're referring to is the fact that you can't extend an array class and hence can't add a method to it:
// No way to do this
int[] array;
array.myMethod();
This means your only option is to make a static helper method somewhere:
// So you have to do this
int[] array;
Utils.myMethod(array);
class Utils {
static void myMethod(int[] array) {
...
}
}
An example of this is the Arrays class, which has lots of static methods for operating on arrays. Conceptually it would be clearer if these methods could be added to the array classes, but you can't do that in Java (you can in other languages like Javascript).
That is why we use other classes like the ArrayList to make them grow dynamically in size. At the core of an arraylist you will simply find an array that is renewed in size whenever the class figures out it necessary. If I'm understanding your question right.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should a method be static?
Usually when writing a static method for a class, the method can be accessed using ClassName.methodName. What is the purpose of using 'static' in this simple example and why should/should not use it here? also does private static defeat the purpose of using static?
public class SimpleTest {
public static void main(String[] args) {
System.out.println("Printing...");
// Invoke the test1 method - no ClassName.methodName needed but works fine?
test1(5);
}
public static void test1(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
public void test2(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
private static void test3(int n1) {
System.out.println("Number: " + n1.toString());
}
}
I had a look at a few tutorials. E.g. http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
My understanding of it is that instead of creating an instance of a class to use that method, you can just use the class name - saves memory in that certain situations there is no point in constructing an object every time to use a particular method.
The purpose of the static keyword is to be able to use a member without creating an instance of the class.
This is what happens here; all the methods (including the private ones) are invoked without creating an instance of SimpleTest.
In this Example,Static is used to directly to access the methods.A private static method defeats the purpose of "Data hiding".
Your main can directly call test1 method as it is also Static,it dosn't require any object to communicate.Main cannot refer non-static members,or any other non-static member cannot refer static member.
"non-static members cannot be referred from a static context"
You can refer This thread for more info about Static members.
static means that the function doesn't require an instance of the class to be called. Instead of:
SimpleTest st = new SimpleTest();
st.test2(5);
you can call:
SimpleTest.test1(5);
You can read more about static methods in this article.
A question about private static has already been asked here. The important part to take away is this:
A private static method by itself does not violate OOP per se, but when you have a lot of these methods on a class that don't need (and cannot*) access instance fields, you are not programming in an OO way, because "object" implies state + operations on that state defined together. Why are you putting these methods on that class, if they don't need any state? -eljenso
static means that the method is not associated with an instance of the class.
It is orthogonal to public/protected/private, which determine the accessibility of the method.
Calling test1 from main in your example works without using the class name because test1 is a static method in the same class as main. If you wanted to call test2 from main, you would need to instantiate an object of that class first because it is not a static method.
A static method does not need to be qualified with a class name when that method is in the same class.
That a method is private (static or not) simply means it can't be accessed from another class.
An instance method (test2 in your example) can only be called on an instance of a class, i.e:
new SimpleTest().test2(5);
Since main is a static method, if you want to call a method of the class without having to instantiate it, you need to make those methods also static.
In regards to making a private method static, it has more readability character than other. There isn't really that much of a difference behind the hoods.
You put in static methods all the computations which are not related to a specific instance of your class.
About the visibility, public static is used when you want to export the functionality, while private static is intended for instance-independent but internal use.
For instance, suppose that you want to assign an unique identifier to each instance of your class. The counter which gives you the next id isn't related to any specific instance, and you also don't want external code to modify it. So you can do something like:
class Foo {
private static int nextId = 0;
private static int getNext () {
return nextId ++;
}
public final int id;
public Foo () {
id = getNext(); // Equivalent: Foo.getNext()
}
}
If in this case you want also to know, from outside the class, how many instances have been created, you can add the following method:
public static int getInstancesCount () {
return nextId;
}
About the ClassName.methodName syntax: it is useful because it specifies the name of the class which provides the static method. If you need to call the method from inside the class you can neglect the first part, as the name methodName would be the closest in terms of namespace.
If I create an instance of a class in Java, why is it preferable to call a static method of that same class statically, rather than using this.method()?
I get a warning from Eclipse when I try to call static method staticMethod() from within the custom class's constructor via this.staticMethod().
public MyClass() { this.staticMethod(); }
vs
public MyClass() { MyClass.staticMethod(); }
Can anyone explain why this is a bad thing to do? It seems to me like the compiler should already have allocated an instance of the object, so statically allocating memory would be unneeded overhead.
EDIT:
The gist of what I'm hearing is that this is bad practice mainly because of readability, and understandably so. What I was really trying to ask (albeit not very clearly) was what differences there are at 'compilation', if any, between calling MyClass.staticMethod() or this.staticMethod().
Static methods are not tied to an instance of the class, so it makes less sense to call it from a this than to call it from Class.staticMethod(), much more readable too.
MyClass.staticMethod() makes it clear that you are calling a static (non-overrideable) method.
this.staticMethod() misleads the reader into thinking that it is an instance method.
staticMethod() is also on the misleading side (though I normally do it that way).
If you think of people reading your code as unfamiliar with it you tend to try to make the code clearer, and this is a case where the code is clearer by having ClassName.method instead of instance.method.
In addition to the other answers which have mentioned making it clear you're using a static method, also note that static methods are not polymorphic, so being explicit with the class name can remove any confusion as to which method is going to be called.
In the code below, it's not entirely obvious that b.test() is going to return "A" if you're expecting the polymorphism of a non-static method:
public class TestStaticOverride
{
public static void main( String[] args )
{
A b = new B();
System.out.println( "Calling b.test(): " + b.test() );
}
private static class A
{
public static String test() { return "A"; }
}
private static class B extends A
{
public static String test() { return "B"; }
}
}
If you change the code to B b = new B(); it will print out "B".
(Whether it's ever a good idea to "override" static methods is probably a discussion for another day...)
Static methods are really not part of your instance - and it will not be able to access any of your instance variables anyway, so I would dare thinking it doesn't make a lot of sense calling it from the constructor.
If your need to initialize static objects use
private static List l = new ArrayList(); static { l.add("something"); }
If you still need to call it its perfectly legal to call local static methods without prefixing your local class name, like this (no eclipse warning)
public MyClass() { staticMethod(); }
Because this. normally reference to instance methods, therefore, it's a bad idea to do that.
So I've been brushing up on my Java skills as of late and have found a few bits of functionality that I didn't know about previously. Static and Instance Initializers are two such techniques.
My question is when would one use an initializer instead of including the code in a constructor? I've thought of a couple obvious possibilities:
static/instance initializers can be used to set the value of "final" static/instance variables whereas a constructor cannot
static initializers can be used to set the value of any static variables in a class, which should be more efficient than having an "if (someStaticVar == null) // do stuff" block of code at the start of each constructor
Both of these cases assume that the code required to set these variables is more complex than simply "var = value", as otherwise there wouldn't seem to be any reason to use an initializer instead of simply setting the value when declaring the variable.
However, while these aren't trivial gains (especially the ability to set a final variable), it does seem that there are a rather limited number of situations in which an initializer should be used.
One can certainly use an initializer for a lot of what is done in a constructor, but I don't really see the reason to do so. Even if all constructors for a class share a large amount of code, the use of a private initialize() function seems to make more sense to me than using an initializer because it doesn't lock you into having that code run when writing a new constructor.
Am I missing something? Are there a number of other situations in which an initializer should be used? Or is it really just a rather limited tool to be used in very specific situations?
Static initializers are useful as cletus mentioned and I use them in the same manner. If you have a static variable that is to be initialized when the class is loaded, then a static initializer is the way to go, especially as it allows you to do a complex initialization and still have the static variable be final. This is a big win.
I find "if (someStaticVar == null) // do stuff" to be messy and error prone. If it is initialized statically and declared final, then you avoid the possibility of it being null.
However, I'm confused when you say:
static/instance initializers can be used to set the value of "final"
static/instance variables whereas a constructor cannot
I assume you are saying both:
static initializers can be used to set the value of "final" static variables whereas a constructor cannot
instance initializers can be used to set the value of "final" instance variables whereas a constructor cannot
and you are correct on the first point, wrong on the second. You can, for example, do this:
class MyClass {
private final int counter;
public MyClass(final int counter) {
this.counter = counter;
}
}
Also, when a lot of code is shared between constructors, one of the best ways to handle this is to chain constructors, providing the default values. This makes is pretty clear what is being done:
class MyClass {
private final int counter;
public MyClass() {
this(0);
}
public MyClass(final int counter) {
this.counter = counter;
}
}
Anonymous inner classes can't have a constructor (as they're anonymous), so they're a pretty natural fit for instance initializers.
I most often use static initializer blocks for setting up final static data, especially collections. For example:
public class Deck {
private final static List<String> SUITS;
static {
List<String> list = new ArrayList<String>();
list.add("Clubs");
list.add("Spades");
list.add("Hearts");
list.add("Diamonds");
SUITS = Collections.unmodifiableList(list);
}
...
}
Now this example can be done with a single line of code:
private final static List<String> SUITS =
Collections.unmodifiableList(
Arrays.asList("Clubs", "Spades", "Hearts", "Diamonds")
);
but the static version can be far neater, particularly when the items are non-trivial to initialize.
A naive implementation may also not create an unmodifiable list, which is a potential mistake. The above creates an immutable data structure that you can happily return from public methods and so on.
Just to add to some already excellent points here. The static initializer is thread safe. It is executed when the class is loaded, and thus makes for simpler static data initialization than using a constructor, in which you would need a synchronized block to check if the static data is initialized and then actually initialize it.
public class MyClass {
static private Properties propTable;
static
{
try
{
propTable.load(new FileInputStream("/data/user.prop"));
}
catch (Exception e)
{
propTable.put("user", System.getProperty("user"));
propTable.put("password", System.getProperty("password"));
}
}
versus
public class MyClass
{
public MyClass()
{
synchronized (MyClass.class)
{
if (propTable == null)
{
try
{
propTable.load(new FileInputStream("/data/user.prop"));
}
catch (Exception e)
{
propTable.put("user", System.getProperty("user"));
propTable.put("password", System.getProperty("password"));
}
}
}
}
Don't forget, you now have to synchronize at the class, not instance level. This incurs a cost for every instance constructed instead of a one time cost when the class is loaded. Plus, it's ugly ;-)
I read a whole article looking for an answer to the init order of initializers vs. their constructors. I didn't find it, so I wrote some code to check my understanding. I thought I would add this little demonstration as a comment. To test your understanding, see if you can predict the answer before reading it at the bottom.
/**
* Demonstrate order of initialization in Java.
* #author Daniel S. Wilkerson
*/
public class CtorOrder {
public static void main(String[] args) {
B a = new B();
}
}
class A {
A() {
System.out.println("A ctor");
}
}
class B extends A {
int x = initX();
int initX() {
System.out.println("B initX");
return 1;
}
B() {
super();
System.out.println("B ctor");
}
}
Output:
java CtorOrder
A ctor
B initX
B ctor
A static initializer is the equivalent of a constructor in the static context. You will certainly see that more often than an instance initializer. Sometimes you need to run code to set up the static environment.
In general, an instance initalizer is best for anonymous inner classes. Take a look at JMock's cookbook to see an innovative way to use it to make code more readable.
Sometimes, if you have some logic which is complicated to chain across constructors (say you are subclassing and you can't call this() because you need to call super()), you could avoid duplication by doing the common stuff in the instance initalizer. Instance initalizers are so rare, though, that they are a surprising syntax to many, so I avoid them and would rather make my class concrete and not anonymous if I need the constructor behavior.
JMock is an exception, because that is how the framework is intended to be used.
There is one important aspect that you have to consider in your choice:
Initializer blocks are members of the class/object, while constructors are not.
This is important when considering extension/subclassing:
Initializers are inherited by subclasses. (Though, can be shadowed)
This means it is basically guaranteed that subclasses are initialized as intended by the parent class.
Constructors are not inherited, though. (They only call super() [i.e. no parameters] implicitly or you have to make a specific super(...) call manually.)
This means it is possible that a implicit or exclicit super(...) call might not initialize the subclass as intended by the parent class.
Consider this example of an initializer block:
class ParentWithInitializer {
protected String aFieldToInitialize;
{
aFieldToInitialize = "init";
System.out.println("initializing in initializer block of: "
+ this.getClass().getSimpleName());
}
}
class ChildOfParentWithInitializer extends ParentWithInitializer{
public static void main(String... args){
System.out.println(new ChildOfParentWithInitializer().aFieldToInitialize);
}
}
output:
initializing in initializer block of: ChildOfParentWithInitializer
init
-> No matter what constructors the subclass implements, the field will be initialized.
Now consider this example with constructors:
class ParentWithConstructor {
protected String aFieldToInitialize;
// different constructors initialize the value differently:
ParentWithConstructor(){
//init a null object
aFieldToInitialize = null;
System.out.println("Constructor of "
+ this.getClass().getSimpleName() + " inits to null");
}
ParentWithConstructor(String... params) {
//init all fields to intended values
aFieldToInitialize = "intended init Value";
System.out.println("initializing in parameterized constructor of:"
+ this.getClass().getSimpleName());
}
}
class ChildOfParentWithConstructor extends ParentWithConstructor{
public static void main (String... args){
System.out.println(new ChildOfParentWithConstructor().aFieldToInitialize);
}
}
output:
Constructor of ChildOfParentWithConstructor inits to null
null
-> This will initialize the field to null by default, even though it might not be the result you wanted.
I would also like to add one point along with all the above fabulous answers . When we load a driver in JDBC using Class.forName("") the the Class loading happens and the static initializer of the Driver class gets fired and the code inside it registers Driver to Driver Manager. This is one of the significant use of static code block.
As you mentioned, it's not useful in a lot of cases and as with any less-used syntax, you probably want to avoid it just to stop the next person looking at your code from spending the 30 seconds to pull it out of the vaults.
On the other hand, it is the only way to do a few things (I think you pretty much covered those).
Static variables themselves should be somewhat avoided anyway--not always, but if you use a lot of them, or you use a lot in one class, you might find different approaches, your future self will thank you.
Note that one big issue with static initializers that perform some side effects, is that they cannot be mocked in unit tests.
I've seen libraries do that, and it's a big pain.
So it's best to keep those static initializers pure only.