Related
I am wondering when to use static methods? Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?
Example:
Obj x = new Obj();
x.someMethod();
...or:
Obj.someMethod(); // Is this the static way?
I'm rather confused!
One rule-of-thumb: ask yourself "Does it make sense to call this method, even if no object has been constructed yet?" If so, it should definitely be static.
So in a class Car you might have a method:
double convertMpgToKpl(double mpg)
...which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But this method (which sets the efficiency of one particular Car):
void setMileage(double mpg)
...can't be static since it's inconceivable to call the method before any Car has been constructed.
(By the way, the converse isn't always true: you might sometimes have a method which involves two Car objects, and still want it to be static. E.g.:
Car theMoreEfficientOf(Car c1, Car c2)
Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car is more important, you shouldn't force a caller to choose one Car as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.
Define static methods in the following scenarios only:
If you are writing utility classes and they are not supposed to be changed.
If the method is not using any instance variable.
If any operation is not dependent on instance creation.
If there is some code that can easily be shared by all the instance methods, extract that code into a static method.
If you are sure that the definition of the method will never be changed or overridden. As static methods can not be overridden.
There are some valid reasons to use static methods:
Performance: if you want some code to be run, and don't want to instantiate an extra object to do so, shove it into a static method. The JVM also can optimize static methods a lot (I think I've once read James Gosling declaring that you don't need custom instructions in the JVM, since static methods will be just as fast, but couldn't find the source - thus it could be completely false). Yes, it is micro-optimization, and probably unneeded. And we programmers never do unneeded things just because they are cool, right?
Practicality: instead of calling new Util().method(arg), call Util.method(arg), or method(arg) with static imports. Easier, shorter.
Adding methods: you really wanted the class String to have a removeSpecialChars() instance method, but it's not there (and it shouldn't, since your project's special characters may be different from the other project's), and you can't add it (since Java is somewhat sane), so you create an utility class, and call removeSpecialChars(s) instead of s.removeSpecialChars(). Sweet.
Purity: taking some precautions, your static method will be a pure function, that is, the only thing it depends on is its parameters. Data in, data out. This is easier to read and debug, since you don't have inheritance quirks to worry about. You can do it with instance methods too, but the compiler will help you a little more with static methods (by not allowing references to instance attributes, overriding methods, etc.).
You'll also have to create a static method if you want to make a singleton, but... don't. I mean, think twice.
Now, more importantly, why you wouldn't want to create a static method? Basically, polymorphism goes out of the window. You'll not be able to override the method, nor declare it in an interface (pre-Java 8). It takes a lot of flexibility out from your design. Also, if you need state, you'll end up with lots of concurrency bugs and/or bottlenecks if you are not careful.
After reading Misko's articles I believe that static methods are bad from a testing point of view. You should have factories instead(maybe using a dependency injection tool like Guice).
how do I ensure that I only have one of something
only have one of something
The problem of “how do I ensure that I
only have one of something” is nicely
sidestepped. You instantiate only a
single ApplicationFactory in your
main, and as a result, you only
instantiate a single instance of all
of your singletons.
The basic issue with static methods is they are procedural code
The basic issue with static methods is
they are procedural code. I have no
idea how to unit-test procedural code.
Unit-testing assumes that I can
instantiate a piece of my application
in isolation. During the instantiation
I wire the dependencies with
mocks/friendlies which replace the
real dependencies. With procedural
programing there is nothing to "wire"
since there are no objects, the code
and data are separate.
A static method is one type of method which doesn't need any object to be initialized for it to be called. Have you noticed static is used in the main function in Java? Program execution begins from there without an object being created.
Consider the following example:
class Languages
{
public static void main(String[] args)
{
display();
}
static void display()
{
System.out.println("Java is my favorite programming language.");
}
}
Static methods in java belong to the class (not an instance of it). They use no instance variables and will usually take input from the parameters, perform actions on it, then return some result. Instances methods are associated with objects and, as the name implies, can use instance variables.
No, static methods aren't associated with an instance; they belong to the class. Static methods are your second example; instance methods are the first.
If you apply static keyword with any method, it is known as static method.
A static method belongs to the class rather than object of a class.
A static method invoked without the need for creating an instance of a class.
static method can access static data member and can change the value of it.
A static method can be accessed just using the name of a class dot static name . . . example : Student9.change();
If you want to use non-static fields of a class, you must use a non-static method.
//Program of changing the common property of all objects(static field).
class Student9{
int rollno;
String name;
static String college = "ITS";
static void change(){
college = "BBDIT";
}
Student9(int r, String n){
rollno = r;
name = n;
}
void display (){System.out.println(rollno+" "+name+" "+college);}
public static void main(String args[]){
Student9.change();
Student9 s1 = new Student9 (111,"Indian");
Student9 s2 = new Student9 (222,"American");
Student9 s3 = new Student9 (333,"China");
s1.display();
s2.display();
s3.display();
} }
O/P: 111 Indian BBDIT
222 American BBDIT
333 China BBDIT
Static methods are not associated with an instance, so they can not access any non-static fields in the class.
You would use a static method if the method does not use any fields (or only static fields) of a class.
If any non-static fields of a class are used you must use a non-static method.
Static methods should be called on the Class, Instance methods should be called on the Instances of the Class. But what does that mean in reality? Here is a useful example:
A car class might have an instance method called Accelerate(). You can only Accelerate a car, if the car actually exists (has been constructed) and therefore this would be an instance method.
A car class might also have a count method called GetCarCount(). This would return the total number of cars created (or constructed). If no cars have been constructed, this method would return 0, but it should still be able to be called, and therefore it would have to be a static method.
Use a static method when you want to be able to access the method without an instance of the class.
Actually, we use static properties and methods in a class, when we want to use some part of our program should exists there until our program is running. And we know that, to manipulate static properties, we need static methods as they are not a part of instance variable. And without static methods, to manipulate static properties is time consuming.
Static:
Obj.someMethod
Use static when you want to provide class level access to a method, i.e. where the method should be callable without an instance of the class.
Static methods don't need to be invoked on the object and that is when you use it. Example: your Main() is a static and you don't create an object to call it.
Static methods and variables are controlled version of 'Global' functions and variables in Java. In which methods can be accessed as classname.methodName() or classInstanceName.methodName(), i.e. static methods and variables can be accessed using class name as well as instances of the class.
Class can't be declared as static(because it makes no sense. if a class is declared public, it can be accessed from anywhere), inner classes can be declared static.
Static methods can be used if
One does not want to perform an action on an instance (utility methods)
As mentioned in few of above answers in this post, converting miles to kilometers, or calculating temperature from Fahrenheit to Celsius and vice-versa. With these examples using static method, it does not need to instantiate whole new object in heap memory. Consider below
1. new ABCClass(double farenheit).convertFarenheitToCelcium()
2. ABCClass.convertFarenheitToCelcium(double farenheit)
the former creates a new class footprint for every method invoke, Performance, Practical. Examples are Math and Apache-Commons library StringUtils class below:
Math.random()
Math.sqrt(double)
Math.min(int, int)
StringUtils.isEmpty(String)
StringUtils.isBlank(String)
One wants to use as a simple function. Inputs are explictly passed, and getting the result data as return value. Inheritence, object instanciation does not come into picture. Concise, Readable.
NOTE:
Few folks argue against testability of static methods, but static methods can be tested too! With jMockit, one can mock static methods. Testability. Example below:
new MockUp<ClassName>() {
#Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
I found a nice description, when to use static methods:
There is no hard and fast, well written rules, to decide when to make a method static or not, But there are few observations based upon experience, which not only help to make a method static but also teaches when to use static method in Java. You should consider making a method static in Java :
If a method doesn't modify state of object, or not using any instance variables.
You want to call method without creating instance of that class.
A method is good candidate of being static, if it only work on arguments provided to it e.g. public int factorial(int number){}, this method only operate on number provided as argument.
Utility methods are also good candidate of being static e.g. StringUtils.isEmpty(String text), this a utility method to check if a String is empty or not.
If function of method will remain static across class hierarchy e.g. equals() method is not a good candidate of making static because every Class can redefine equality.
Source is here
Static methods are the methods in Java that can be called without creating an object of class. It is belong to the class.
We use static method when we no need to be invoked method using instance.
A static method has two main purposes:
For utility or helper methods that don't require any object state.
Since there is no need to access instance variables, having static
methods eliminates the need for the caller to instantiate the object
just to call the method.
For the state that is shared by all
instances of the class, like a counter. All instance must share the
same state. Methods that merely use that state should be static as
well.
You should use static methods whenever,
The code in the method is not dependent on instance creation and is
not using any instance variable.
A particular piece of code is to be shared by all the instance methods.
The definition of the method should not be changed or overridden.
you are writing utility classes that should not be changed.
https://www.tutorialspoint.com/When-to-use-static-methods-in-Java
In eclipse you can enable a warning which helps you detect potential static methods. (Above the highlighted line is another one I forgot to highlight)
I am wondering when to use static methods?
A common use for static methods is to access static fields.
But you can have static methods, without referencing static variables. Helper methods without referring static variable can be found in some java classes like java.lang.Math
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
The other use case, I can think of these methods combined with synchronized method is implementation of class level locking in multi threaded environment.
Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?
If you need to access method on an instance object of the class, your method should should be non static.
Oracle documentation page provides more details.
Not all combinations of instance and class variables and methods are allowed:
Instance methods can access instance variables and instance methods directly.
Instance methods can access class variables and class methods directly.
Class methods can access class variables and class methods directly.
Class methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to.
Whenever you do not want to create an object to call a method in your code just declare that method as static. Since the static method does not need an instance to be called with but the catch here is not all static methods are called by JVM automatically. This privilege is enjoyed only by the main() "public static void main[String... args]" method in java because at Runtime this is the method Signature public "static" void main[] sought by JVM as an entry point to start execution of the code.
Example:
public class Demo
{
public static void main(String... args)
{
Demo d = new Demo();
System.out.println("This static method is executed by JVM");
//Now to call the static method Displ() you can use the below methods:
Displ(); //By method name itself
Demo.Displ(); //By using class name//Recommended
d.Displ(); //By using instance //Not recommended
}
public static void Displ()
{
System.out.println("This static method needs to be called explicitly");
}
}
Output:-
This static method is executed by JVM
This static method needs to be called explicitly
This static method needs to be called explicitly
This static method needs to be called explicitly
The only reasonable place to use static methods are probably Math functions, and of course main() must be static, and maybe small factory-methods. But logic should not be kept in static methods.
I am wondering when to use static methods? Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?
Example:
Obj x = new Obj();
x.someMethod();
...or:
Obj.someMethod(); // Is this the static way?
I'm rather confused!
One rule-of-thumb: ask yourself "Does it make sense to call this method, even if no object has been constructed yet?" If so, it should definitely be static.
So in a class Car you might have a method:
double convertMpgToKpl(double mpg)
...which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But this method (which sets the efficiency of one particular Car):
void setMileage(double mpg)
...can't be static since it's inconceivable to call the method before any Car has been constructed.
(By the way, the converse isn't always true: you might sometimes have a method which involves two Car objects, and still want it to be static. E.g.:
Car theMoreEfficientOf(Car c1, Car c2)
Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car is more important, you shouldn't force a caller to choose one Car as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.
Define static methods in the following scenarios only:
If you are writing utility classes and they are not supposed to be changed.
If the method is not using any instance variable.
If any operation is not dependent on instance creation.
If there is some code that can easily be shared by all the instance methods, extract that code into a static method.
If you are sure that the definition of the method will never be changed or overridden. As static methods can not be overridden.
There are some valid reasons to use static methods:
Performance: if you want some code to be run, and don't want to instantiate an extra object to do so, shove it into a static method. The JVM also can optimize static methods a lot (I think I've once read James Gosling declaring that you don't need custom instructions in the JVM, since static methods will be just as fast, but couldn't find the source - thus it could be completely false). Yes, it is micro-optimization, and probably unneeded. And we programmers never do unneeded things just because they are cool, right?
Practicality: instead of calling new Util().method(arg), call Util.method(arg), or method(arg) with static imports. Easier, shorter.
Adding methods: you really wanted the class String to have a removeSpecialChars() instance method, but it's not there (and it shouldn't, since your project's special characters may be different from the other project's), and you can't add it (since Java is somewhat sane), so you create an utility class, and call removeSpecialChars(s) instead of s.removeSpecialChars(). Sweet.
Purity: taking some precautions, your static method will be a pure function, that is, the only thing it depends on is its parameters. Data in, data out. This is easier to read and debug, since you don't have inheritance quirks to worry about. You can do it with instance methods too, but the compiler will help you a little more with static methods (by not allowing references to instance attributes, overriding methods, etc.).
You'll also have to create a static method if you want to make a singleton, but... don't. I mean, think twice.
Now, more importantly, why you wouldn't want to create a static method? Basically, polymorphism goes out of the window. You'll not be able to override the method, nor declare it in an interface (pre-Java 8). It takes a lot of flexibility out from your design. Also, if you need state, you'll end up with lots of concurrency bugs and/or bottlenecks if you are not careful.
After reading Misko's articles I believe that static methods are bad from a testing point of view. You should have factories instead(maybe using a dependency injection tool like Guice).
how do I ensure that I only have one of something
only have one of something
The problem of “how do I ensure that I
only have one of something” is nicely
sidestepped. You instantiate only a
single ApplicationFactory in your
main, and as a result, you only
instantiate a single instance of all
of your singletons.
The basic issue with static methods is they are procedural code
The basic issue with static methods is
they are procedural code. I have no
idea how to unit-test procedural code.
Unit-testing assumes that I can
instantiate a piece of my application
in isolation. During the instantiation
I wire the dependencies with
mocks/friendlies which replace the
real dependencies. With procedural
programing there is nothing to "wire"
since there are no objects, the code
and data are separate.
A static method is one type of method which doesn't need any object to be initialized for it to be called. Have you noticed static is used in the main function in Java? Program execution begins from there without an object being created.
Consider the following example:
class Languages
{
public static void main(String[] args)
{
display();
}
static void display()
{
System.out.println("Java is my favorite programming language.");
}
}
Static methods in java belong to the class (not an instance of it). They use no instance variables and will usually take input from the parameters, perform actions on it, then return some result. Instances methods are associated with objects and, as the name implies, can use instance variables.
No, static methods aren't associated with an instance; they belong to the class. Static methods are your second example; instance methods are the first.
If you apply static keyword with any method, it is known as static method.
A static method belongs to the class rather than object of a class.
A static method invoked without the need for creating an instance of a class.
static method can access static data member and can change the value of it.
A static method can be accessed just using the name of a class dot static name . . . example : Student9.change();
If you want to use non-static fields of a class, you must use a non-static method.
//Program of changing the common property of all objects(static field).
class Student9{
int rollno;
String name;
static String college = "ITS";
static void change(){
college = "BBDIT";
}
Student9(int r, String n){
rollno = r;
name = n;
}
void display (){System.out.println(rollno+" "+name+" "+college);}
public static void main(String args[]){
Student9.change();
Student9 s1 = new Student9 (111,"Indian");
Student9 s2 = new Student9 (222,"American");
Student9 s3 = new Student9 (333,"China");
s1.display();
s2.display();
s3.display();
} }
O/P: 111 Indian BBDIT
222 American BBDIT
333 China BBDIT
Static methods are not associated with an instance, so they can not access any non-static fields in the class.
You would use a static method if the method does not use any fields (or only static fields) of a class.
If any non-static fields of a class are used you must use a non-static method.
Static methods should be called on the Class, Instance methods should be called on the Instances of the Class. But what does that mean in reality? Here is a useful example:
A car class might have an instance method called Accelerate(). You can only Accelerate a car, if the car actually exists (has been constructed) and therefore this would be an instance method.
A car class might also have a count method called GetCarCount(). This would return the total number of cars created (or constructed). If no cars have been constructed, this method would return 0, but it should still be able to be called, and therefore it would have to be a static method.
Use a static method when you want to be able to access the method without an instance of the class.
Actually, we use static properties and methods in a class, when we want to use some part of our program should exists there until our program is running. And we know that, to manipulate static properties, we need static methods as they are not a part of instance variable. And without static methods, to manipulate static properties is time consuming.
Static:
Obj.someMethod
Use static when you want to provide class level access to a method, i.e. where the method should be callable without an instance of the class.
Static methods don't need to be invoked on the object and that is when you use it. Example: your Main() is a static and you don't create an object to call it.
Static methods and variables are controlled version of 'Global' functions and variables in Java. In which methods can be accessed as classname.methodName() or classInstanceName.methodName(), i.e. static methods and variables can be accessed using class name as well as instances of the class.
Class can't be declared as static(because it makes no sense. if a class is declared public, it can be accessed from anywhere), inner classes can be declared static.
Static methods can be used if
One does not want to perform an action on an instance (utility methods)
As mentioned in few of above answers in this post, converting miles to kilometers, or calculating temperature from Fahrenheit to Celsius and vice-versa. With these examples using static method, it does not need to instantiate whole new object in heap memory. Consider below
1. new ABCClass(double farenheit).convertFarenheitToCelcium()
2. ABCClass.convertFarenheitToCelcium(double farenheit)
the former creates a new class footprint for every method invoke, Performance, Practical. Examples are Math and Apache-Commons library StringUtils class below:
Math.random()
Math.sqrt(double)
Math.min(int, int)
StringUtils.isEmpty(String)
StringUtils.isBlank(String)
One wants to use as a simple function. Inputs are explictly passed, and getting the result data as return value. Inheritence, object instanciation does not come into picture. Concise, Readable.
NOTE:
Few folks argue against testability of static methods, but static methods can be tested too! With jMockit, one can mock static methods. Testability. Example below:
new MockUp<ClassName>() {
#Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
I found a nice description, when to use static methods:
There is no hard and fast, well written rules, to decide when to make a method static or not, But there are few observations based upon experience, which not only help to make a method static but also teaches when to use static method in Java. You should consider making a method static in Java :
If a method doesn't modify state of object, or not using any instance variables.
You want to call method without creating instance of that class.
A method is good candidate of being static, if it only work on arguments provided to it e.g. public int factorial(int number){}, this method only operate on number provided as argument.
Utility methods are also good candidate of being static e.g. StringUtils.isEmpty(String text), this a utility method to check if a String is empty or not.
If function of method will remain static across class hierarchy e.g. equals() method is not a good candidate of making static because every Class can redefine equality.
Source is here
Static methods are the methods in Java that can be called without creating an object of class. It is belong to the class.
We use static method when we no need to be invoked method using instance.
A static method has two main purposes:
For utility or helper methods that don't require any object state.
Since there is no need to access instance variables, having static
methods eliminates the need for the caller to instantiate the object
just to call the method.
For the state that is shared by all
instances of the class, like a counter. All instance must share the
same state. Methods that merely use that state should be static as
well.
You should use static methods whenever,
The code in the method is not dependent on instance creation and is
not using any instance variable.
A particular piece of code is to be shared by all the instance methods.
The definition of the method should not be changed or overridden.
you are writing utility classes that should not be changed.
https://www.tutorialspoint.com/When-to-use-static-methods-in-Java
In eclipse you can enable a warning which helps you detect potential static methods. (Above the highlighted line is another one I forgot to highlight)
I am wondering when to use static methods?
A common use for static methods is to access static fields.
But you can have static methods, without referencing static variables. Helper methods without referring static variable can be found in some java classes like java.lang.Math
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
The other use case, I can think of these methods combined with synchronized method is implementation of class level locking in multi threaded environment.
Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?
If you need to access method on an instance object of the class, your method should should be non static.
Oracle documentation page provides more details.
Not all combinations of instance and class variables and methods are allowed:
Instance methods can access instance variables and instance methods directly.
Instance methods can access class variables and class methods directly.
Class methods can access class variables and class methods directly.
Class methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to.
Whenever you do not want to create an object to call a method in your code just declare that method as static. Since the static method does not need an instance to be called with but the catch here is not all static methods are called by JVM automatically. This privilege is enjoyed only by the main() "public static void main[String... args]" method in java because at Runtime this is the method Signature public "static" void main[] sought by JVM as an entry point to start execution of the code.
Example:
public class Demo
{
public static void main(String... args)
{
Demo d = new Demo();
System.out.println("This static method is executed by JVM");
//Now to call the static method Displ() you can use the below methods:
Displ(); //By method name itself
Demo.Displ(); //By using class name//Recommended
d.Displ(); //By using instance //Not recommended
}
public static void Displ()
{
System.out.println("This static method needs to be called explicitly");
}
}
Output:-
This static method is executed by JVM
This static method needs to be called explicitly
This static method needs to be called explicitly
This static method needs to be called explicitly
The only reasonable place to use static methods are probably Math functions, and of course main() must be static, and maybe small factory-methods. But logic should not be kept in static methods.
Ok, so I am about to embarrass my self here but I am working on a project that I will need to get some help on so I need to get some conventions down so I don't look too stupid. I have only been doing java for 2 months and 100% of that has been on Android.
I need some help understanding setting up variables and why I should do it a certain way.
Here is an example of my variables list for a class:
Button listen,feed;
Context context = this;
int totalSize = 0;
int downloadedSize = 0;
SeekBar seek;
String[] feedContent = new String[1000];
String[] feedItems = new String[1000];
ListView podcast_list = null;
HtmlGrabber html = new HtmlGrabber();
String pkg = "com.TwitForAndroid";
TextView progress = null;
long cp = 0;
long tp = 0;
String source = null;
String pageContent = null;
String pageName = "http://www.shanescode.com";
DataBaseHelper mdbHelper = new DataBaseHelper(this);
int songdur = 0;
So all of these are variables that I want to use in all through the whole class. Why would I make something a static, or a final. I understand Public but why make something private?
Thanks for your help and please don't be too harsh. I just need some clarification.
These words all alter the way the variable to which they are applied can be used in code.
static means that the variable will only be created once for the entire class, rather than one for each different instance of that class.
public class MyClass{
public static int myNumber;
}
In this case the variable is accessed as MyClass.myNumber, rather than through an instance of MyClass. Static variables are used when you want to store data about the class as a whole rather than about an individual instance.
final prevents the variable's value from changing after it is set the first time. It must be given an initial value either as part of its declaration:
public final int myNumber = 3;
or as part of the class's constructor:
public MyClass(int number){
this.myNumber = 3;
Once this is done, the variable's value cannot be changed. Keep in mind, though, that if the variable is storing an object this does not prevent the object's variable from being changed. This keyword is used to keep a piece of data constant, which can make writing code using that data much easier.
private modifies the visibility of the variable. A private variable can be accessed by the instance which contains it, but not outside that:
public class MyClass{
private int myNumber;
public void changeNumber(int number){
this.myNumber = number; //this works
}
}
MyClass myInstance = new MyClass();
myInstance.myNumber = 3; //This does not work
myInstance.changeNumber(3) //This works
Visibility is used to control how a class's variables can be used by other code. This is very important when writing code which will be used by other programmers, in order to control how they can access the internal structure of your classes. Public and private are actually only two of the four possible levels of visibility in Java: the others are protected and "no (visibility) modifier" (a.k.a not public or private or protected). The differences between these four levels is detailed here.
static = same for all instances of a class.
final = unchanging (reference) for a particular instance.
If you needed some field (aka a class variable) to be shared by all instances of a class (e.g., a constant) then you might make it static.
If you know some field is immutable (at least, it's reference is immutable) in an instance, then it is good practice to make it final. Again, constants would be a good example of a field to make final; anything that is constant within an instance from construction time on is also a good candidate for final.
A search for "java final static" gives pretty useful further reference on the use of those keywords.
The use of the private keyword controls what can accessed by other classes. I'd say it's biggest use is to help developers "do the right thing" - instead of accessing the internals of the implementation of another class, which could produce all sorts of unwanted behavior, it forces using accessor/mutator methods, which the class implementor can use to enforce the appropriate constraints.
Private
The idea behind using private is information hiding. Forget about software for a second; imagine a piece of hardware, like an X-Box or something. Somewhere on it, it has a little hatch to access the inside, usually sporting a sticker: "open this up and warranty is void."
Using private is sticking a sticker like that in your software component; some things are 'inside' only, and while it would be easy for anyone to open it up and play with the inside anyways, you're letting them know that if they do, you're not responsible for the unexpected behavior that results.
Static
The static keyword does not mean "same for all instances of a class"; that's a simplification. Rather, it is the antonym of "dynamic". Using the static keyword means "There is no dynamic dispatching on this member." This means that the compiler and not the run-time determines what code executes when you call this method.
Since thee are no instances of objects at compile-time this means that a static member has no access to an instance.
An example:
public class Cat {
public static void speak() { System.out.println("meow"); }
}
public class Lion extends Cat {
public static void speak() { System.out.println("ROAR"); }
}
// ...
public static void main(String argv[]) {
Cat c = new Lion();
c.speak();
}
The above prints "meow" - not "roar" - because speak is a static member, and the declared type of c is Cat, so the compiler builds in such a way that Cat.speak is executed, not Lion.speak. Were there dynamic dispatching on static members, then Lion.speak would execute, as the run-time type of c is Lion.
Another thing that might trip you up is this:
Not everything has to be a class level variable; you should have a variable defined for the smallest scope it needs to be defined.
So as an example, suppose your class only has one method which uses your TextView progress variable. Move that declaration into the method that needs it. This way it tidies things up and helps you make more robust code by separating out things that are really separate.
I don't know why you would make anything private.
Folks will chime in and say that private is a Very Important Thing.
Some folks will claim that you can't do encapsulation without private. Most of this seems to be privacy for privacy's sake.
If you are selling your code to someone else, then you must carefully separate the interface elements of your class from the implementation details of your class. In this case, you want to make the implementation private (or protected) so that -- for legal purposes -- the code you sell doesn't expose too much of the implementation details.
Otherwise, if you're not selling it, don't waste a lot of time on private.
Invest your time in separating Interface from Implementation. Document the Interface portions carefully to be sure you're playing by the rules. Clearly and cleanly keep the implementation details separate. Consider using private as a way to have the compiler "look over your shoulder" to be sure you've really separated interface from implementation.
One of the aspects of the object oriented approach that has made it so wildly popular is that you can hide your variables inside of a class. The class becomes like a container. Now you as the programmer get to decide how you want the users of your class to interact with it. In Java, the tradition is to provide an API -- a public interface for your class using methods of the class.
To make this approach work, you declare your variables as private ( which means only methods within your class can access them ) and then provide other methods to access them. For example,
private int someNumber;
This variable can only be accessed from within your class. Do you think others might need access to it from outside of the class? You would create a method to allow access:
public int getSomeNumber()
{
return someNumber;
}
Perhaps users of your class will also need the ability to set someNumber as well. In that case, you provide a method to do that as well:
public void setSomeNumber( int someNumber )
{
this.someNumber = someNumber;
}
Why all of this work just to get access to a class member that you could just as easily declare as public? If you do it using this approach, you have control over how others access the data in your class. Imagine that you want to make sure that someNumber only gets set to be a number < 100. You can provide that check in your setSomeNumber method. By declaring your variables to have private access, you protect your class from getting used incorrectly, and make it easier on everyone who needs to use it -- including yourself!
Declaring a variable to have static access means that you do not need an instance of the class to access the variable. In Java, generally you write a class and then create an instance of it. You can have as many instances of that class as you want, and they all keep track of their own data. You can also declare variables that are part of the class itself, and this is where the static keyword comes in. If you create a variable...
static int classVariable = 0;
the variable can be accessed without a class instance. For example, you might see this done from time to time:
public static final int MY_CONSTANT = 1;
While there are better ways to do this now, it is still a common pattern. You use this variable without any instance of the class like this:
myInstance.setSomeNumber( MyClass.MY_CONSTANT );
java.awt.Color uses static variables this way. You can also declare methods to be static ( look at public static void main, the starting point for your programs ). Statics are useful, but use them sparingly because creating instances of classes can often result in better designs.
Finally ( pun intended ), why would you ever want to declare a variable to be final? If you know that the value should never change, declaring it as final means that if you write some code that tries to change that value, the compiler will start complaining. This again helps protect from making silly mistakes that can add up to really annoying bugs.
If you look at the static variable example above, the final keyword is also used. This is a time when you have decided that you want to make a variable public, but also want to protect it from being changed. You do this by making it public and final.
Is the below class immutable:
final class MyClass {
private final int[] array;
public MyClass(int[] array){
this.array = array;
}
}
No it is not because the elements of the array can still be changed.
int[] v1 = new int[10];
MyClass v2 = new MyClass(v1);
v1[0] = 42; // mutation visible to MyClass1
My two cents regarding immutability rules (which I retained from reading Effective Java - a great book!):
Don't provide methods that can modify the state of an object.
Make all your fields final.
Make sure that your class is non-extendable.
Make all your fields private.
Provide exclusive access to any fields or components of your class that can be changed. Essentially this applies to your situation (as explained by JaredPar). A person that uses your class still has a reference to your array. The opposite is the case where you return a reference to an component of your class. In this case, always create defensive copies. In your case, you should not assign the reference. Instead, copy the array that the user of your class provides, into your internal component.
"Immutability" is a convention between the programmer and himself. That convention may be more or less enforced by the compiler.
Instances of a class are "immutable" if they do not change during the normal course of the application code execution. In some cases we know that they do not change because the code actually forbids it; in other cases, this is just part of how we use the class. For instance, a java.util.Date instance is formally mutable (there is a setTime() method on it) but it is customary to handle it as if it were immutable; this is just an application-wide convention that the Date.setTime() method shall not be called.
As additional notes:
Immutability is often thought of in terms of "external characteristics". For instance, Java's String is documented to be immutable (that's what the Javadoc says). But if you look at the source code, you will see that a String instance contains a private field called hash which may change over time: this is a cache for the value returned by hashCode(). We still say that String is immutable because the hash field is an internal optimization which has no effect visible from the outside.
With reflection, the most private of instance fields can be modified (including those marked as final), if the programmer wishes so hard enough. Not that it is a good idea: it may break assumptions used by other pieces of code using the said instance. As I said, immutability is a convention: if the programmer wants to fight himself, then he can, but this can have adverse side-effects on productivity...
Most Java values are actually references. It is up to you to define whether a referenced object is part of what you consider to be "the instance contents". In your class, you have a field which references an (externally provided) array of integers. If the contents of that array are modified afterwards, would you consider that this breaks immutability of your MyClass instance ? There is no generic answer to that question.
There is no way to make an array immutable. That is there is no way to keep any client code from setting or removing or adding items to the array.
Here is a truly immutable alternative:
private static class MyClass
{
private List<Integer> list;
private MyClass(final int[] array)
{
final List<Integer> tmplist = new ArrayList<Integer>(array.length);
for (int i : array)
{
tmplist.add(array[i]);
}
this.list = Collections.unmodifiableList(tmplist);
}
}
To make a class immutable, you need to both ensure that all the fields on it are final, and that the types of those fields are immutable too.
This can be a pain to remember, but there is a tool to help you.
Pure4J provides an annotation #ImmutableValue, which you can add to an interface or class.
There is a maven plugin to check at compile-time that you are meeting the rules on immutability following this.
Hope this helps.
Suppose you need to define a class which all it does is hold constants.
public static final String SOME_CONST = "SOME_VALUE";
What is the preferred way of doing this?
Interface
Abstract Class
Final Class
Which one should I use and why?
Clarifications to some answers:
Enums - I'm not going to use enums, I am not enumerating anything, just collecting some constants which are not related to each other in any way.
Interface - I'm not going to set any class as one that implements the interface. Just want to use the interface to call constants like so: ISomeInterface.SOME_CONST.
Use a final class, and define a private constructor to hide the public one.
For simplicity you may then use a static import to reuse your values in another class
public final class MyValues {
private MyValues() {
// No need to instantiate the class, we can hide its constructor
}
public static final String VALUE1 = "foo";
public static final String VALUE2 = "bar";
}
in another class :
import static MyValues.*
//...
if (VALUE1.equals(variable)) {
//...
}
Your clarification states: "I'm not going to use enums, I am not enumerating anything, just collecting some constants which are not related to each other in any way."
If the constants aren't related to each other at all, why do you want to collect them together? Put each constant in the class which it's most closely related to.
My suggestions (in decreasing order of preference):
1) Don't do it. Create the constants in the actual class where they are most relevant. Having a 'bag of constants' class/interface isn't really following OO best practices.
I, and everyone else, ignore #1 from time to time. If you're going to do that then:
2) final class with private constructor This will at least prevent anyone from abusing your 'bag of constants' by extending/implementing it to get easy access to the constants. (I know you said you wouldn't do this -- but that doesn't mean someone coming along after you won't)
3) interface This will work, but not my preference giving the possible abuse mention in #2.
In general, just because these are constants doesn't mean you shouldn't still apply normal oo principles to them. If no one but one class cares about a constant - it should be private and in that class. If only tests care about a constant - it should be in a test class, not production code. If a constant is defined in multiple places (not just accidentally the same) - refactor to eliminate duplication. And so on - treat them like you would a method.
As Joshua Bloch notes in Effective Java:
Interfaces should only be used to define types,
abstract classes don't prevent instanciability (they can be subclassed, and even suggest that they are designed to be subclassed).
You can use an Enum if all your constants are related (like planet names), put the constant values in classes they are related to (if you have access to them), or use a non instanciable utility class (define a private default constructor).
class SomeConstants
{
// Prevents instanciation of myself and my subclasses
private SomeConstants() {}
public final static String TOTO = "toto";
public final static Integer TEN = 10;
//...
}
Then, as already stated, you can use static imports to use your constants.
My preferred method is not to do that at all. The age of constants pretty much died when Java 5 introduced typesafe enums. And even before then Josh Bloch published a (slightly more wordy) version of that, which worked on Java 1.4 (and earlier).
Unless you need interoperability with some legacy code there's really no reason to use named String/integer constants anymore.
enums are fine. IIRC, one item in effective Java (2nd Ed) has enum constants enumerating standard options implementing a [Java keyword] interface for any value.
My preference is to use a [Java keyword] interface over a final class for constants. You implicitly get the public static final. Some people will argue that an interface allows bad programmers to implement it, but bad programmers are going to write code that sucks no matter what you do.
Which looks better?
public final class SomeStuff {
private SomeStuff() {
throw new Error();
}
public static final String SOME_CONST = "Some value or another, I don't know.";
}
Or:
public interface SomeStuff {
String SOME_CONST = "Some value or another, I don't know.";
}
Just use final class.
If you want to be able to add other values use an abstract class.
It doesn't make much sense using an interface, an interface is supposed to specify a contract. You just want to declare some constant values.
Aren't enums best choice for these kinds of stuff?
Or 4. Put them in the class that contains the logic that uses the constants the most
... sorry, couldn't resist ;-)
The best approach for me, is enum:
public enum SomeApiConstants {;
public static final String SOME_CONST = "SOME_VALUE";
//may be in hierarchy
public enum ApiMapping {;
public static final String VERSION = "/version";
public static final String VERSION_LIST = "/list/{type}";
}
}
Pros:
clean code
the private constructor does not need to be defined
attempt to instantiate is validated in compile time as java: enum types may not be instantiated
prevents to clone and deserialization
One of the disadvantage of private constructor is the exists of method could never be tested.
Enum by the nature concept good to apply in specific domain type, apply it to decentralized constants looks not good enough
The concept of Enum is "Enumerations are sets of closely related items".
Extend/implement a constant interface is a bad practice, it is hard to think about requirement to extend a immutable constant instead of referring to it directly.
If apply quality tool like SonarSource, there are rules force developer to drop constant interface, this is a awkward thing as a lot of projects enjoy the constant interface and rarely to see "extend" things happen on constant interfaces