Related
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
The very common beginner mistake is when you try to use a class property "statically" without making an instance of that class. It leaves you with the mentioned error message:
You can either make the non static method static or make an instance of that class to use its properties.
What the reason behind this? Am not concern with the solution, rather the reason.
private java.util.List<String> someMethod(){
/* Some Code */
return someList;
}
public static void main(String[] strArgs){
// The following statement causes the error.
java.util.List<String> someList = someMethod();
}
You can't call something that doesn't exist. Since you haven't created an object, the non-static method doesn't exist yet. A static method (by definition) always exists.
The method you are trying to call is an instance-level method; you do not have an instance.
static methods belong to the class, non-static methods belong to instances of the class.
The essence of object oriented programming is encapsulating logic together with the data it operates on.
Instance methods are the logic, instance fields are the data. Together, they form an object.
public class Foo
{
private String foo;
public Foo(String foo){ this.foo = foo; }
public getFoo(){ return this.foo; }
public static void main(String[] args){
System.out.println( getFoo() );
}
}
What could possibly be the result of running the above program?
Without an object, there is no instance data, and while the instance methods exist as part of the class definition, they need an object instance to provide data for them.
In theory, an instance method that does not access any instance data could work in a static context, but then there isn't really any reason for it to be an instance method. It's a language design decision to allow it anyway rather than making up an extra rule to forbid it.
I just realized, I think people shouldn't be exposed to the concept of "static" very early.
Static methods should probably be the exception rather than the norm. Especially early on anyways if you want to learn OOP. (Why start with an exception to the rule?) That's very counter-pedagogical of Java, that the "first" thing you should learn is the public static void main thing. (Few real Java applications have their own main methods anyways.)
I think it is worth pointing out that by the rules of the Java language the Java compiler inserts the equivalent of "this." when it notices that you're accessing instance methods or instance fields without an explicit instance. Of course, the compiler knows that it can only do this from within an instance method, which has a "this" variable, as static methods don't.
Which means that when you're in an instance method the following are equivalent:
instanceMethod();
this.instanceMethod();
and these are also equivalent:
... = instanceField;
... = this.instanceField;
The compiler is effectively inserting the "this." when you don't supply a specific instance.
This (pun intended) bit of "magic help" by the compiler can confuse novices: it means that instance calls and static calls sometimes appear to have the same syntax while in reality are calls of different types and underlying mechanisms.
The instance method call is sometimes referred to as a method invocation or dispatch because of the behaviors of virtual methods supporting polymorphism; dispatching behavior happens regardless of whether you wrote an explicit object instance to use or the compiler inserted a "this.".
The static method call mechanism is simpler, like a function call in a non-OOP language.
Personally, I think the error message is misleading, it could read "non-static method cannot be referenced from a static context without specifying an explicit object instance".
What the compiler is complaining about is that it cannot simply insert the standard "this." as it does within instance methods, because this code is within a static method; however, maybe the author merely forgot to supply the instance of interest for this invocation — say, an instance possibly supplied to the static method as parameter, or created within this static method.
In short, you most certainly can call instance methods from within a static method, you just need to have and specify an explicit instance object for the invocation.
The answers so far describe why, but here is a something else you might want to consider:
You can can call a method from an instantiable class by appending a method call to its constructor,
Object instance = new Constuctor().methodCall();
or
primitive name = new Constuctor().methodCall();
This is useful it you only wish to use a method of an instantiable class once within a single scope. If you are calling multiple methods from an instantiable class within a single scope, definitely create a referable instance.
If we try to access an instance method from a static context , the compiler has no way to guess which instance method ( variable for which object ), you are referring to. Though, you can always access it using an object reference.
A static method relates an action to a type of object, whereas the non static method relates an action to an instance of that type of object. Typically it is a method that does something with relation to the instance.
Ex:
class Car might have a wash method, which would indicate washing a particular car, whereas a static method would apply to the type car.
if a method is not static, that "tells" the compiler that the method requires access to instance-level data in the class, (like a non-static field). This data would not be available unless an instance of the class has been created. So the compiler throws an error if you try to call the method from a static method.. If in fact the method does NOT reference any non-static member of the class, make the method static.
In Resharper, for example, just creating a non-static method that does NOT reference any static member of the class generates a warning message "This method can be made static"
The compiler actually adds an argument to non-static methods. It adds a this pointer/reference. This is also the reason why a static method can not use this, because there is no object.
So you are asking for a very core reason?
Well, since you are developing in Java, the compiler generates an object code that the Java Virtual Machine can interpret. The JVM anyway is a binary program that run in machine language (probably the JVM’s version specific for your operating system and hardware was previously compiled by another programming language like C in order to get a machine code that can run in your processor). At the end, any code is translated to machine code. So, create an object (an instance of a class) is equivalent to reserve a memory space (memory registers that will be processor registers when the CPU scheduler of the operating system put your program at the top of the queue in order to execute it) to have a data storage place that can be able to read and write data. If you don’t have an instance of a class (which happens on a static context), then you don’t have that memory space to read or write the data. In fact, like other people had said, the data don’t exist (because from the begin you never had written neither had reserved the memory space to store it).
Sorry for my english! I'm latin!
The simple reason behind this is that Static data members of parent class
can be accessed (only if they are not overridden) but for instance(non-static)
data members or methods we need their reference and so they can only be
called through an object.
A non-static method is dependent on the object. It is recognized by the program once the object is created.
Static methods can be called even before the creation of an object. Static methods are great for doing comparisons or operations that aren't dependent on the actual objects you plan to work with.
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
I have a singleton class.
When accessing the methods of the class I have the choice of two possibilities.
Create those methods as instance specific and then get the instance and invoke them
Create those methods as static and invoke them and they will get the instance
For example:
Class Test{
private int field1;
Test instance;
private Test(){};
private Test getInstance(){
if (instance == null)
instance = new Test();
return instance;
}
public int method1() { return field1;}
public static int method2() {return getInstance().field1;}
}
Now, elsewhere I can write
int x = Test.getInstance().method1();
int y = Test.method2();
Which is better?
I can think of a 3rd alternative where I use "instance" directly in the static method and then capture the exception if it is null and instantiate it and then re-invoke itself.
I could, in theory, just make the whole lot static.
However, this will create me problems when saving the state at activity close since the serialization doesn't save static.
I think the first one is cleaner.
However, keep in mind that under some extreme cases, Android may kill your static instances. See this for example: http://code.google.com/p/acra/ .
A workaround I've found somewhere for this, is to keep a reference to your singleton from the Application class, as well. I don't know how problem-proof this is, though.
You should avoid making everything static. Some people would even say that a singleton is not done.
The whole point of the singleton pattern is that you can change the implementation. In most cases you use it to keep the possibility open to "hook" in some other implementations of this functionality later.
Read: when deciding in favor of singleton plan for a setInstance method too, not just for a getInstance. - If this does not make sense, just use a plain static class.
In the other hand singletons are out of season, if you want to be hip and all that. Do a search for "eliminating global state". There are some Google-sponsored talks about it too. In short: your code will be more testable and helps you avoid some dependency chaos. (Besides being hip and all, it is definitely a step into the right direction).
In my personal opinion having static methods is bad design in the first place. It, of course, depends on the program itself, but allowing a class to have static method will have impact on the whole design. Some reasoning behind my statement:
If static method can easily change state of some object, sooner or later bugs will emerge
If you publish static method with your program, every client that will use it will have a very strong dependency on your code. If you decide to remove or change this method someday - you will break every single client that used your class.
So, if you can - avoid it.
If, from any reason, you will insist on having static method, I guess the first solution is better. That's how singleton should work. You should obtain a reference to a SINGLETON OBJECT via static method, but this object should be then used according to all principles from Object Oriented Programming.
I have a class as follows
class Myclass{
//no instance variables
static boolean validate(MyObj oj){
//impl
}
}
Now if 2 thread calls static method Myclass.validate(param) with different parameters at the same time ,will it work correctly? If yes/no, how?
Is my approach correct? I want to put some validation logic or some custom conversion utility in such static methods.
1- Call is safe since the obj parameter is local to the method. However ensure that
The Obj is not shared by different threads. If it is then sate is not
modified. (should be immutable)
The object re3fernce is not passed to any alien method, which
might be not thread safe.
You can mark the parameter as final.
2- Its OK to have static methods for classes which don't have any state.
If you don't have any instance variables, you have a utility class.
public enum Utility {;
public static boolean validate(MyObj obj) ....
}
However a better approach is to move the method to the first parameter type, if you can.
public class MyObj {
public boolean validate() ....
}
Provided the arguments are not shared, two threads can call the same method without thread safety issue.
If this is for validation, or conversion a utility class may be a better choice if you want more than one way to validate or convert the MyObj type.
You use case is a perfect fit for an Utility class and making the utility class methods static will help you use the class without instantiating it (Hence avoiding object littering and GC overhead ).
Thread safety is not an issue here as you are using any shared variable (class variables). So you are safe that way.
So both #1 and 2# will work.
Yes, it will work correctly. Parameters passed to a method lives in
a memory area called the "stack" and each thread will have it's own
stack.
I would say yes
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.