java basics static method - java

can a static method be invoked before even a single instances of the class is constructed?

absolutely, this is the purpose of static methods:
class ClassName {
public static void staticMethod() {
}
}
In order to invoke a static method you must import the class:
import ClassName;
// ...
ClassName.staticMethod();
or using static imports (Java 5 or above):
import static ClassName.staticMethod;
// ...
staticMethod();

As others have already suggested, it is definitely possible to call a static method on a class without (previously) creating an instance--this is how Singletons work. For example:
import java.util.Calendar;
public class MyClass
{
// the static method Calendar.getInstance() is used to create
// [Calendar]s--note that [Calendar]'s constructor is private
private Calendar now = Calendar.getInstance();
}
If you mean, "is it possible to automatically call a specific static method before the first object is initialized?", see below:
public class MyClass
{
// the static block is garanteed to be executed before the
// first [MyClass] object is created.
static {
MyClass.init();
}
private static void init() {
// do something ...
}
}

Yes, that is exactly what static methods are for.
ClassName.staticMethodName();

Yes, because static methods cannot access instance variables, so all the JVM has to do is run the code.

Static methods are meant to be called without instantiating the class.

Yes, you can access it by writing ClassName.methodName before creating any instance.

Not only can you do that, but you should do it.

In fact, there are a lot of "utility classes", like Math, Collections, Arrays, and System, which are classes that cannot be instantiated, but whose whole purpose is to provide static methods for people to use.

Yes, that's definitely possible. For example, consider the following example...
class test {
public static void main(String arg[]) {
System.out.println("hello");
}
}
...if then we run it, it does execute, we never created a instance of the class test. In short, the statement public static void main(String arg[]) means execute the main method without instantiating the class test.

Related

Can we create an object of the class in which main function is defined in Java?

Is it possible to create object of class in which main method resides.I have been searching for this answer but I have been told that it depends on compiler some compiler will allow while others will not.Is that true?
Yes? The main method is just an entry point. The class is like any other, except it has an additional public static method. The main method is static and therefore not part of the instance of the object, but you shouldn't be using the main method anyway except for starting the program.
public class Scratchpad {
public static void main(String[] args) {
Scratchpad scratchpad = new Scratchpad();
scratchpad.someMethod();
}
public Scratchpad() {
}
private void someMethod() {
System.out.println("Non-static method prints");
}
}
Yes, you can create object for the class which has main method. There is no difference in this class and a class which don't have main method with respect to creating objects and using.

Initialization of static method when class loads in java

I have a doubt regarding static methods. In the program written below, output will be: main. I understand this because main is a static method, so when class loads, it executes. If so, the same principle should apply for met() also, right? As it is also static. Why does only main executes whereas met() doesn't when the class loads?
public class Test {
static void met() {
System.out.println("method");
}
public static void main(String[] args) {
System.out.println("main");
}
}
No, this isn't correct.
Neither of these methods are called when the class is loaded.
main() is called when you execute the class Test.
Only static initialisers are called when the class is loaded. A static initialiser looks like this:
static
{
//code here
}
A class is loaded before the main() method is executed, and therefore its static initialiser is run before the main() method. The following snippet will make that clear.
public class TestA
{
static
{
System.out.println( "hello" );
}
public static void main( String[] args )
{
System.out.println( "bye" );
}
}
Let me explain it in detail
Types of methods There are basically two types of methods,
Instance methods
Class Methods
Instance Methods Belong to objects and you will always need an object/instance to call such methods.
static methods are the class methods and they can be called directly by class name, there is no need to have an instance of class to call them.
For example,
class Demo{
public void sayHello(){
System.out.println("Hello");
}
public static void sayHi(){
System.out.println("Hi")
}
public static void main(String args[]){
Demo.sayHi(); //Call to static/class method
Demo.sayHello(); //It will not work
Demo d = new Demo();
d.sayHello(); //It will work.
}
}
**But NONE of them gets called automatically when class loads.**
Main Difference between the two
In memory there is ONLY ONE copy of static methods which will be available for all the objects. But whenever an object is created a new copy of instance method is created for the object, so each object has its own instance method. Similar to instance & class variables.
Static methods are not meant to be run automatically, instead they are shared by all objects. Why main() method is called, because it is the entry point of the program.
Apart from them, there is static block which is called automatically only once when the class is loaded.
Example
class Main{
static{
System.out.println("static block");
}
public static void main(String args[]){
System.out.println("main");
}
}
Output will be
static block
main
main() method is not executed because it's static, it executes because it is the Entry Point for any Java program. If you want something to run, you'll need to call it from the main method. No other methods are automatically called when the class is executed.
Not at all. The main method will only run if that particular class is ran as entry point.
That met() method will not run until it has been called. The main difference it has with instance methods, is that you do not need to create an instance of the class in order to run it, you can simply run it through the class itself: Test.met();
What you mean is a static block:
private static String description;
static{
description = "this runs on loading the class";
}
You can use static block instead of static method, to print it before main method like this -
public class Test
{
static{
System.out.println("method");
}
public static void main(String[] args){
System.out.println("main");
}
}
met() is a static method, it will be in memory when the class is loaded, you need to call it.. You could use a static block to print "method".
If you want to execute on load , just intialise it as static block,
static{
System.out.println("method");
}
Because static blocks are executed once the class loads . And among other static methods main() has the high priority
No static method will get called when you call it only, you are mixing static initializer and static method
it prints main because when you run Java application it invokes main() method
there is a difference between static methods, static blocks and static variables. As you do not call the static method, it will not print
To make it print you will need to call Test.met ();
Alternatively you could have it set as a static block
as in
static {
System.out.println("static block");
}
This will be called as soon as Test is loaded.
Not all static method will be called by default when a program runs.
From Docs
The java tool launches a Java application. It does this by starting a Java runtime environment, loading a
specified class, and invoking that class's main method. The method declaration must look like the following:
**public static void main(String args[])**
So, main will be called by JVM and someone should call met() so that it is executed.
What you understood is wrong. Because whenever class loads JVM creates Class class object and int that class class object all static methods resides. main method is entry point for JVM thats why it is executing, JVM internally calling Main method. Whenever Class loads that time it only executes Static internalization blocks.
Main() is only executed because it is the entry point.
For more information you can read the documentation.

Static method invocation

Can we call a static method without mentioning the class name in Java?
Yes you can. Check out static imports. You have to mention the class name in the import statement, but after that you don't have to.e.g. from the linked article:
import static java.lang.Math.abs;
import static java.lang.Math.max;
int xDist = abs(destination.getX() - x);
int yDist = abs(destination.getY() - y);
return max(xDist, yDist);
Introduced in Java 5.
Yes, you can call a static method without mentioning the class name. There's the import static (see JLS 7.5.4 for exact mechanism), but even without it, if the name can be resolved (see JLS 15.12.1 for exact mechanism) without fully qualifying the class, it will work.
The following code compiles and prints "Hello world!" as expected.
import static java.lang.System.out;
public class Test {
static String greeting() {
return "Hello world!";
}
public static void main(String[] args) {
out.println(greeting());
}
}
out in the println statement is actually a static field access of the class java.lang.System, not a static method, but it's a static member access nonetheless. greeting() is a static method invocation, and the class name can be omitted since its reference can be resolved without fully qualifying the name.
Now let's ask if this is a good idea. Unless you're calling a static method from within its class, IT'S NOT a good idea generally to omit the class name!!!
Let's focus on static import first. A quote from the guide:
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.
The case is made stronger by the following example:
class Base {
void task1() {
System.out.println("Base.task1");
}
static void task2() {
System.out.println("Base.task2");
}
}
class Child extends Base {
void task1() {
System.out.println("Child.task1");
}
static void task2() {
System.out.println("Child.task2");
}
}
//....
Base sweetChildOMine = new Child();
sweetChildOMine.task1(); // prints "Child.task1"
sweetChildOMine.task2(); // prints "Base.task2"
What a surprise! You'd think that since sweetChildOMine has a reference to an instance of Child, sweetChildOMine.task2() should print "Child.task2" because it's overridden by Child class, right?
WRONG! A static method can not be overridden! It can only be hidden by a subclass! In fact, if you tried to do the right thing and add the #Override annotation to task2, it would not compile!
From JLS 15.12.4.4 Locate method to invoke:
If the invocation mode is static, no target reference is needed and overriding is not allowed. Method m of class T is the one to be invoked.
In fact, this problem is covered in Java Puzzlers Puzzle 48: All I Get Is Static. The conclusion given at the end of the puzzle is this:
In summary, qualify static methods invocations with a class name, or don't qualify them at all if you're invoking them from within their own class, but never qualify them with an expression. Also, avoid hiding static methods. Together, these guidelines help eliminate the misleading appearance of overriding with dynamic dispatch for static methods.
It is best to follow all these recommendations together, so:
If you're calling a static method within its own class, don't qualify
Otherwise, qualify with the class name
If you're doing this a lot within one class, consider static import of that specific method
Try not to static import all members with *
Never qualify with an expression
Don't hide a static method; you can't #Override it, it'll only cause confusion
See also:
Why doesn’t Java allow overriding of static methods ?
When do you use Java’s #Override annotation and why?
Yes, adding to Brian Agnew you can call static methods through an instance of that class type as well.
Yes you can call a static method without the class name. For example, if you are calling it within another static method of the same class.
public class TestStatic{
static void hello()
{
System.out.println("Hello World");
}
static void hello2()
{
hello();
System.out.println("Welcome to java");
}
public static void main(String[] args)
{
hello2();
}
}
Yes.
class CallStaticMethodTest {
public static void staticMethodOne() {
System.out.println("Static method one");
}
// Invoke from a non-static method
public void instanceMethodOne() {
staticMethodOne();// Calling static method without mentioning the class name
}
// Invoke from another static method:
public static void staticMethodTwo() {
staticMethodOne();
}
}

how does the following code work

Currently I'm trying to invoke it like this:
class Test {
public static void test() {
System.out.println("hi");
}
public static void main(String[] args) {
Test t = null;
t.test();
}
}
The output of the code is hi
Try Test.test() with the class name before the dot.
Static methods are called on the class itself not instances of the class.
You don't need to instantiate Test for calling a static method. Your main could be look like this:
public static void main(String[] args) {
Test.test();
}
Static methiods should be invoked with the class name, without the need for creating an instance of the class, as in
ClassName.methodName(args);
or
methodName(args); // from other static methods of the same class.
You can also refer to static methods with an object reference like
instanceName.methodName(args)
but this is discouraged because it does not make it clear that they are class methods.
So in your case:
Test.test();
or
test();
from the main method will do.
Try:
Test.test();
You are in the same class, you can simply call test() from main().
for (Method m : Class.forName ("Test").getDeclaredMethods ()) {
if (Modifier.isStatic (m.getModifiers ()) {
m.invoke (null);
}
}
just for lulz
The good thing about static methods and static variables is that you do not need an instance of the class to use it.
Normally you would create an instance and call the method
Test myClass = new Text();
myClass.test();
However with static methods the first line is not necessary, You just need to write the Class name at the start
Test.test();
However, in static methods you are not able to access any instance variables inside the Test class - unless they are also static!
By the way. The code works fine without any nullpointerexception
This code prints hi
I wanted to know what happens internally when a reference is used to invoke a static method.
It works because when invoking a static method using a reference, the reference is not used. The compiler looks at the declared/static/compile-time type of the expression the method is being called on, and uses that type to find the static method.
You gain nothing by calling a static method on a variable, and you can confuse people who think a polymorphic call is occurring.
Call Test.test(). As the main method is static and in the same class so you can also directly call test() too.
class Test {
public static void test() {
System.out.println("hi");
}
public static void main(String[] args) {
Test.test();
}
}

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