how does the following code work - java

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();
}
}

Related

new instance of the class in java main method

I am new to java, I was wondering why I need to create a new instance of the class to use its non-static methods in the main method but not in the other methods like the following
public class Test {
public void test(){
System.out.println("test");
}
public static void main(String args[]){
test(); // error Cannot make a static reference to the non-static method test() from the type Test
}
public void tst(){
test(); // no errors
}
}
Look, main is static method. You call it from the class which hasn't been initialized yet. You can do that, however you can't call Test#test without having an instance of Test.
Working code:
public class Test {
public void test(){
System.out.println("test");
}
public static void main(String args[]){
Test test = new Test();
test.test();
}
public void tst(){
test(); // no errors
}
}
Explanation:
Non-static methods must be called on objects. Objects are created with new keyword. Sometimes, there are methods which return new objects, but they call new inside.
Static methods can be called without creating an object. You then need to declare them static. How? Simply add static before return type.
Example of how static methods work:
public class Test {
public void test(){
System.out.println("test");
}
public static void main(String args[]){
tst();
Test test = new Test();
test.test();
}
public static void tst(){
Test test = new Test();
test.test();
}
}
There were no errors in tst() because you called the method which you saw from that scope. It means that if there was an object of class Test created, you could call tst and test. If you tried to call tst before my refactor, you would have been warned the same warning.
By definition
Static methods, belong to the class, meaning you can use them by calling
ClassName.methodName();
Instance methods (non-static) must be called on instances of an object of a certain class.
like
Test test = new Test();
test.test();
You can't call a non-static method from static area for this any how you have to create an object and through this object only you can call this method.
Or if you want to call directly the method from static area then make method also static.
Why?? Normally in java there are 3 types of variable based on our declare position 1) local variable 2) Instance variable and 3) static variable, same as instance method and static method also.
NOTE Static method or block execute at the time of class loading and that time you are trying to call a normal method and the scope of normal method is same as the scope of object so, without creating object u can't think also about a normal/instance method.
Think of static methods as existing outside of any instance of that class. It is really an instance-less method. In order to call non-static methods, you must reference an instance in order to invoke it.
Another way to look at the issue is from the point of view of the variables. Static variables are shared by all instances of the class and do not belong to a single instance.
public class Test {
private static int var1 = 0;
private int var2 = 0;
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test();
var1++;
test1.testMethod();
test2.testMethod();
System.out.println("var1=" + var1);
System.out.println("test1.var2=" + test1.var2);
System.out.println("test2.var2=" + test2.var2);
}
private void testMethod() {
var1++;
var2++;
}
}
will produce the following
var1=3
test1.var2=1
test2.var2=1
Static methods are also shared by all instances of a class so do not have direct access to non-static variables.
In java a class has fields and methods (or functions). Keyword 'static' can be added to both of these entities.
Entities marked with keyword 'static' are class related and other entities are instance related. For accessing static fields or methods of a class we require only the class and its instance (created by using new keyword) is not required to be created.
Methods and fields which are not marked static belong to an active instance of the class.
Now suppose there is a class Test.java and we have no instance of it. We can call any of its method which is marked as static. Try thinking an answer to : "From inside an static method (without an instance of the class) how can we call a method or how can we access a field which belongs to some instance?"
For acessing non static field or method from an static method we need an instance. If the 'calling method' is non static then it must have been invoked on an object. If now we call another method from this non static 'calling method' we can eaisly do that as that method will be invoked on the same object as on which the 'calling method' has been invoked upon.
As mentioned by Xavi in his answer you can also refer to
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html for understanding about 'static'.
All non static methods and fields have 'this' (https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html) associated with them, which refers to the current active instance of the class.
Hence 'main' method being static can not call any non static method without instance of the class 'Test'
That's lesson 1: create an object from your class:
Test test = new Test ();
test.test(); // will print test
public static void main is a static method, meaning it's not being executed in the context of a particular instance of the class.
Any method not qualified with static needs to be invoked in the context of a specific instance of the class, that's why it's necessary to instance an object or dispose an instance of the class to invoke if from a static context, or to call it from a non-static context such as your public void tst() method.
I'd strongly recommend going through some basic Java tutorials such as Understanding Class Members.
To call static method, you only need the class, while "non-static" we need a instance of the particular class(create an object of the class).

Couple of questions on java method calling

1: I have a program like..
public class Test{
void dispose(){
System.out.println("disposing");
}
Test t=new Test();
public static void main(String[] args){
t.dispose();
}
}
why cant I call dispose method from main()? if its static and non static relation, why the below code works?
public class Test{
void dispose(){
System.out.println("disposing");
}
public static void main(String[] args){
Test t=new Test();
t.dispose();
}
}
2: should always the method call code shold be in method? because, the below code is not working..
public class Test{
void dispose(){
System.out.println("disposing");
}
Test t=new Test();
t.dispose();
public static void main(String[] args){
}
}
Please clarify me..
Example 1
You are in a static method (main) and trying to access a non-static variable t. You have declared the variable t as:
Test t=new Test();
This has created it as a member variable of the class. Instead you need to declare it as:
static Test t=new Test();
Now the static method can access it (although this is generally not a good way to do things).
Example 2
You are now declaring the variable t as a local variable inside the main method so it is valid to access it from within main.
Example 3
With the exception of initalizer blocks (which you don't need to worry about) all code must go inside a method.
I guess you come from a background in Procedural language like C.
Java is different. It's object-orriented.
Coming to your Question . . . .
Ans1: It's correct to say that you don’t necessarily have to create an instance of a class to use the methods of the class. If a method is declared with the static keyword, the method can be called without first creating an instance of the class. That’s because static methods are called from classes, not from objects.
BUT, you can not call non-static method from a static context (here as in static method main()). WHY?
Because 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.
However even that's not the exact case over here
You may feel that you have created an instance of the class at line 5 of your code but to to the compiler, it doesn't exists. It's outside the main() method, which is the first thing looked for in any run-able Java program. The compiler then ropes in other parts as required. You can't have executable code that is not in a method, look at your object initialization. In second block of code, the compiler sees the object initialization, so program executes.
Ans2: YES. As mentioned before, You can't have executable code that is not in a method
Illustration:
class DeclarationTest
{
int a = 5;
int b = 10;
int c = a + b;//it is Ok, this is a declaration statement for c
/*
int c;
c = a + b; ------> this is not Ok, you are performing an action here this must be inside a method!
*/
}
If that was the case it would make having methods a bit less useful. . . Think about it.
why cant I call dispose method from main()? if its static and non static relation, why the below code works?
Since you have a instance of Test, so you can use that even in static context.
should always the method call code shold be in method?
Yes. exactly. Either in methods, static block or in constructor. Other places not allowed.
Before starting everything let me clear what is an Class variable and an Object Variable
Class Variable : Static variable, which can be accessed without initializing the Class
Object Variable: non static Variable which can only be accessed on CLass instantiation
So in your case, when the main Gets Called, the Class is not initiated, so the object doesnt get initialized, so you cannot call the dispose method.
The reason the second block doesn't work is because of the static relation.
If a method is not static, then it must have an instance to be accessed. That is why, creating an instance of the class allows you to call the method.
If you made the dispose method static, then you could directly call the method since there is only a single instance of it.
Here is a link to a different question that explains it well:
calling non-static method in static method in Java
Hope this helps :)
why cant I call dispose method from main()? if its static and non
static relation, why the below code works?
non-static variable t cannot be referenced from a static context(compiler exception).
You should always remember that the jvm searches for the main() method and executes it. Methods and blocks are initialized after that.
note:- You always compile and run the class which contains the main method.
You are declaring the variable t as a local variable inside the main method so it is valid to access it from within main.
should always the method call code should be in method?
Yes method calls always need to be inside of a method or in the constructor or initialization block, even static block .
When a java program is being executed JVM looks for main method. Within the main if you don't write anything nothing will happen.
public class Test{
void dispose(){
System.out.println("disposing");
}
Test t=new Test(); //That's ok.
t.dispose(); //causes compilation error
public static void main(String[] args){
//Executed as soon as you run your program.
}
}
You want to call dispose(). What do you want? Call dispose() on object of test as t.dispose() or you can call it using Test.dispose();
Method 1:
public class Test{
void dispose(){
System.out.println("disposing");
}
public static void main(String[] args){
Test t=new Test(); //You need a reference to Test object
t.dispose(); //to call its methods
}
}
Is dispose() in Test static? No... So, you must call it by using Test object.
If dispose() in Test static? then...
Method 2:
public class Test{
static void dispose(){
System.out.println("disposing");
}
public static void main(String[] args){
Test.dispose(); // Since dispose() is static.
}
}
You can't call non static methods by using Class Reference. You must use Class object But you can call static methods by using class objects (not recommended). You should call it using Class Reference.
Method 3: (Not recommended)
public class Test{
static void dispose(){
System.out.println("disposing");
}
public static void main(String[] args){
Test t = new Test();
t.dispose(); //Static members should be accessed using class name
}
}
Yes, you can not call non-static object or variables inside static block. If you declare object as static then your code will work as follow.
public class Test{
void dispose(){
System.out.println("disposing");
}
static Test t=new Test();
public static void main(String[] args){
t.dispose();
}
}
You can also try something like below:
public class Test{
void dispose(){
System.out.println("disposing");
}
{
dispose();
}
public static void main(String[] args){
Test t=new Test();
}
}
Also, we can declare object outside method in class but we can not call method outside method or block.

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.

java basics static method

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.

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