Why using public static methods in Java? - java

If I understand the meaning of each keyword correctly, public means the method is accessible by anybody(instances of the class, direct call of the method, etc), while static means that the method can only be accessed inside the class(not even the instances of the class). That said, the public keyword is no use in this situation as the method can only be used inside the class. I wrote a little program to test it out and I got no errors or warnings without putting the public key word in front of the method. Can anyone please explain why public static methods are sometimes use? (e.g. public static void main(String[] args))
Thank you in advance!

Static methods mean you do not need to instantiate the class to call the method, it does't mean you cannot call it from anywhere you want in the application.

Others have already explained the right meaning of static.
Can anyone please explain why public static methods are sometimes use?
Maybe the most famous example is the public static void main method - the standard entry point for java programs.
It is public because it needs to be called from the outside world.
It is static because it won't make sanse to start a program from an object instance.
Another good examle is a utility class, one that only holds static methods for use of other classes. It dosen't need to be instantiated (sometimes it even can't), but rather supply a bounch of "static" routines to perform, routines that does not depend on a state of an object. The output is a direct function of the input (ofcourse, it might also be subject to other global state from outside). this is actually why it is called static.
That said, the static keyword is not always used because you want to have access to some members in a class without instantiating it, but rather because it makes sense. You keep a property that is shared among all instances in one place, instead of holding copies of it in each instance.
That leads to a third common use of public static (or even public static final) - the definition of constants.

A public static method is a method that does not need an instance of the class to run and can be run from anywhere. Typically it is used for some utility function that does not use the member variables of a class and is self contained in its logic.
The code below chooses a path to store an image based on the image file name so that the many images are stored in a tree of small folders.
public static String getImagePathString(String key){
String res = key.substring(3, 4)+File.separator+
key.substring(2, 3)+File.separator+
key.substring(1, 2)+File.separator+
key.substring(0, 1);
return res;
}
It needs no other information (it could do with a safety check on the size of key)

A quick guide to some of the options...
public class Foo {
public static void doo() {
}
private static void dont() {
}
public Foo() {
doo(); // this works
dont(); // this works
Foo.doo(); // this works
Foo.dont(); // this works
this.doo(); // this works but is silly - its just Foo.doo();
this.dont(); // this works but is silly - its just Foo.dont();
}
public static void main(String[] args) {
doo(); // this works
dont(); // this works
Foo.doo(); // this works
Foo.dont(); // this works
Foo foo = new Foo();
foo.doo(); // this works but is silly - its just Foo.doo();
}
}
public class Another {
public static void main(String[] args) {
Foo.doo(); // this works
Foo.dont(); // this DOESN'T work. dont is private
doo(); // this DOESN'T work. where is doo()? I cant find it?
}
}

Related

Java default constructor without initialization

I have a class similar to the below one with all static methods. Hence the class was not initialized while used in other classes. I have to check a condition before invoking any static methods from this class. Even if i add a default constructor it will not get called. Could someone suggest ideas to have solution without instantiating this class in all of its usages? It need be a default constructor could be a simple other solution.
I need to check everytime the network connectivity before making the call. Static Initializer gets called only first time on load.
public class ABCServerUtil {
public static boolean checkServer() {...bla...bla...}
}
I need some thing like below piece of code to be called and to be exit.
public ABCServerUtil(){
if(!isNetworkOnline())
return;
}
If you need to check the condition every time one of the static methods is called, you don't have much choice but to do what you're doing: Call a method to do the check at the beginning of each of those methods.
If you only need to check the condition once when the class is initially loaded/initialized, you can use a static initializer:
public class ABCServerUtil {
static {
// Code here runs when the class is loaded
}
// ...
}
Use a static Initialization block
static {
//whatever code for initialization
}
A class can have any number of static initialization blocks
they can appear anywhere in the class body
static initialization blocks are called in the order that they appear in the source code.
You should be called every time when method called
public class Test {
public static void checkServer() {
if (!checkNetwork()) {
return;
}
}
public static void checkClient() {
if (!checkNetwork()) {
return;
}
}
private static boolean checkNetwork() {
return true; // or false depending on network condition
}
}
You can use a static initialiser.
static {
// code here
}
It will be run before any method of property (static or otherwise) of the class is first accessed.
you can directly call a static method with the class name like this,
boolean val=ABCServerUtil.checkServer();
some tutorial is given here
Since there's already 5 answers saying the same thing and none of them seem to be what you're after:
A tool like Byte Buddy sounds like what you need.
I think that this is your solution: Static initializer in Java
In practice you need a block of code executed the first time that your class is loaded.

How is the Static method(main) able to grab hold of non static method(constructor) and execute it?

Seems like a very basic query but I was pondering how the static method main() below is able to execute a non static method(the constructor obviously) from it using the new keyword. Though I understand that new brings onto the table a few other things as well but how should I convince myself that this isn't an exception to the rule that static and non static methods can't using non static and static context respectively?
Below is the sample code:
public class ConstructorTest {
ConstructorTest(String str)
{
System.out.println("Constructor Printing "+str);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ConstructorTest cnst=new ConstructorTest("here");
}
}
The above code actually prints --> Constructor Printing here
or in other words executing the body of a Non static method from a Static method?
Any plausible explanations are welcome.
The Java Tutorial states that
[...] Constructors are not members.
Therefore, there is no problem in calling them, since they are not bound to instances of your class. This would not make sense - hence, you cannot do the following:
Thing thing = new Thing();
Thing anotherThing = thing.Thing();
A constructor is not a method, so you cannot apply "method logic" to them.
In case you want to know more, the whole instantiation process is very well documented in the JLS. See 12.5. Creation of New Class Instances.
Actually constructor is compiled into the static method, this is how JVM internally creates instances of classes.
You are executing non-static code, but you are not doing it in a static context.
for instance:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
do();
}
}
This can not work, since do is an instance method, which might run code that is specific to the instance. So, how would the VM know which instance to use, or what value x should have?
Now, to first use a constructor, which is possible from any context:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
C1 t = new C1();
t.do();
}
}
Here, even though you are calling the method from within a static method, you are using it through an instance, so not in a static context.
ConstructorTest is not a method.
its an constructor,and you can use the constructor for initialize class property.
you can also initialize the static variable from the constructor like that :-
public class XYZ
{
static int i=0;
public XYZ() {
i=1;//not an compile time error
}
public static void doSome(){}
public static void main(String[] args) {
}
}
On a formal language level you should read the line
ConstructorTest cnst = new ConstructorTest("here")
as a class instance creation expression. As a matter of fact, this is not a call to a constructor or any other method.
The instance creation does many steps, like allocating memory for the new object, initializing the fields, calling constructors and initializer blocks. See JLS §12.5 for a detailed step-by-step description. Thus being said, the constructor invocation is only a part of the instance creation.
Additionally, you might see constructors as being static parts of the class. In fact, constructor declaration are not members (see JLS §8.8) and thus they are not overridable (as static methods also). Beware: This is only half true. When being inside the constructor you already have the instance created, and you are able to call other instance methods and/or access instance fields.

Using a non-static variable in a static method JAVA

So I am writing a very large java code, within this code I want it to output files in a particular file format. In this instance it is going to be a simple .txt file.
The data I am outputting is a series of coordinates, these coordinates have undergone rotation using an angle that is determined by the user prior to this code section.
The code to write the file is obviously in a static method but the angle I am calling is a non-static variable... how do I call this and get it to work?
Basically you have to pass an instance of the object containing the non-static variable to the static function and access it there.
That would look something like this:
public class ObjectToBeWritten {
private int nonStaticVariable;
public ObjectToBeWritten() {
// ...
}
public int getNonStaticVariable() {
return nonStaticVariable;
}
public static void outputToTxt(ObjectToBeWritten object) {
nonStaticVariable = object.getNonStaticVariable();
// ...
}
}
Then you just call ObjectToBeWritten.outputToTxt(object) with the object that contains the non-static variable.
Non static means that it belongs to some class instance(object). So pass this object to your static method and/or create those objects inside it.
you should know non-static method belongs to Object ,but static method belongs to Class.Therefore the getNonStaticVariables method and nonStaticVariable should be static or change the outputToTxt to non-static.
My first thought is that perhaps either your non-static variable or your static method belong somewhere else.
When a class hold variable, non-static contents, it's probably a bad idea to provide static accessor functions that use that variable. I think the best solution is to separate the two, giving the responsibility of storing the mutable data in some Data Provider class that can provide a DEFENSIVE COPY of this variable. Perhaps you don't see the need for it because your example deals with a primitive value. But, if you were to change that to some object reference, you could run into all sorts of problems; one of which is that your code will not be thread-safe.
public class MyDataProvider {
private Object nonStaticVariable;
public MyDataProvider () {
// ...
}
public Object getNonStaticVariable() {
Object copy = new Object();
// copy the internals from nonStaticVariable to copy
return copy;
}
}
Then, your utility class can use the copy of nonStaticVariable to do its work...
public class MyUtilityClass {
public static void outputToTxt(Object nonStaticVariableCopy) {
// do your work
}
}
This solution solves all those problems and is much more robust:
Allows a non-static variable to be used by a static method
Your code will be thread-safe because you are using a copy of the non-static variable instead of the original variable.
Separation of concerns: Your utility class doesn't store any variables; thus all methods of the utility class can be static (like Java's Math class), and your Data Provider can be the container that holds your variables.

How to hide a public method?

I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?
You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
Then you instantiate the class B, but only let the type A be known to others...
Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.
You could use package level instead of public. That way it can only be called by your application.
If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
Here's some code for a client of this Singleton:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.
So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.
The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
If you want to limit some parts of the project to only see method1(), then what you do is describe it in an interface, and have the class implement that interface:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to method2(). All you need do is create a new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().
This is a similar approach to that advocated in #MathiasSchwarz's answer, but is much more flexible:
The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).
An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.
You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?
There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.
Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html
I have seen many Java programmers do something like this:
public static void main(String args[]) {
new MyClass();
}
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.

Invoke static initializer again

Once a class is loaded is there a way to invoke static initializers again?
public class Foo {
static {
System.out.println("bar");
}
}
Edit:
I need to invoke the static initializer because I didn't write the original class and the logic I need to invoke is implemented in the static initializer.
Put the initalisation code in a separate public static method, so you can call it from the static initializer and from elsewhere?
One circumstance in which the logic would be run more than once is if the class is loaded multiple times by different ClassLoaders. Note that in this instance, they are essentially different classes.
Generally, though, these are one-shot deals. If you want to be able to invoke the logic multiple times, do as others have suggested and put it in a static method.
I agree with Earwicker's answer. Just extract the static initialization to a separate static method.
public class Foo {
static {
Foo.initialize();
}
public static void initialize() {
System.out.println("bar");
}
}
In case you really want the exact answer to your exact question, the answer is no. It's not possible to invoke a static initializer or an instanceInitializer via reflection.
The docs clearly says :
for getDeclaredMethod(String name) :
If the name is "<init>" or "<clinit>" a NoSuchMethodException is raised.
for getDeclaredMethods() :
The class initialization method is not included in the returned array.
So no, it's not possible to invoke it, even via reflection.
you could try extending the class which contains the static code, and then put in your own static initializer. Not quite sure if it works, but :
public class OldBadLibraryClass {
static {
System.out.println("oldBadLibrary static init");
}
}
//next file
public class MyBetterClass extends OldBadLibraryClass {
static {
System.out.println("MyBetterClass init");
}
}
public class Test {
public static void main(String[] args) {
new MyBetterClass();
}
}
see if the above prints in the order you expect. On my machine, it worked.
Though this is totally a hack, and is quite brittle. It would really be much better to modify the old class to have an init() method that can be overridden.
Here https://stackoverflow.com/a/19302726/2300018 is a post from me, where I re-load a utility class to re-run the static initializer for unit testing.

Categories