java class instance - java

I have a simple Java theory question. If I write a class that contains a main() method along with some other methods, and within that main method invoke an instance of the class (say new Class()), I'm a bit confused why a recursion doesn't occur. Let's say I'm writing a graphing program, where the other methods in the class create a window and plot data; in the main method I call an instance of the class itself, and yet only one window appears. That's great, and it's what I wanted, but intuition suggests that if I create an instance of a class from within itself, some sort of recursion should occur. What prevents this? Here is an example (in my mind, I'm wondering what prevents unwanted recursion):
public class example{
method1(){create Jpane}
method2(){paint Jpane}
method 3(){do some computations}
public static void main(String[] args){
new example(); // or create Jblah(new example());
}
}

I think you're confusing the main method - which is just the entry point of the program - with a constructor.
For example, if you wrote:
public class Example {
public Example() {
new Example(); // Recursive call
}
public static void main(String[] args) {
// Will call the constructor, which will call itself... but main
// won't get called again.
new Example();
}
}
Then that would go bang.

The main method does not get executed automatically when you instance a class. It simply can be used as an entry point to an application - and then will be executed once.

Recursion isn't a bad thing. I suspect you are asking why there isn't an infinite recursion.
The big concept you are missing is that when you call new Example() you are allocating memory and then invoking just one method (the constructor). The main() is only invoked at the start of the whole program unless you explicitly call it.
--- edited to add
public class MyMainClass {
public static void main(String arg[]) {
Calculator c = new Calculator();
int x = c.factorial(5);
}
}
class Calculator {
Calculator() { }
public int factorial(int x) {
if (x > 1) return x * factorial(x - 1);
else return 1; // WARNING: wrong answer for negative input
}
}
Since factorial doesn't use any instance variable, it could have been declared static and called as Calculator.factoral(5); without even using new, but I din't do that since showing off new was the whole point of the example.

just because you have a main method in the class doesn' mean that it will be called every time you create the class.
Java looks for main as an entry point for the program, and calls it upon startup. Any objects you instantiate from their do not call main, since as far as java is concerned, it has done its job of making the entry point to the program.

Related

Java executing static imports

Following the this code of block of the image what is the expecting result
on the rabbit class I'm confused if the way the Hole class is instantiated is valid I'm assuming it is so the output will be
Here is the image with the code:
"dig'
"dig"
9
The expected output would be
dig dig 9
The first call:
Hole.dig()
is a standard static method call which I assume doesn't surprise you.
The second call:
new Hole().dig()
is pretty bad code. (fine for when you are learning but not so great in the workplace). Your editor likely is warning you about this. This is calling the static dig() method but based on the declared/implied type of new Hole();
It is bad code because it will give you the idea that the instance has something to say about which method is being called.
for instance:
public static void main(String[] args) {
new A().printMe();
new C().printMe();
A whichOne = new C();
whichOne.printMe();
}
public static class A {
public static void printMe() {
System.out.println("A");
}
}
public static class C extends A {
public static void printMe() {
System.out.println("C");
}
}
this will print A , not C as you might expect. You are creating a C object but after you put it into an A variable, the static method will use the class of the containing variable to decide which method to call.
new C().printMe();
A whichOne = new C();
whichOne.printMe();
// gives C , A
This is confusing and generally frowned upon.
Lastly the static import:
import static hole.Hole.*; // import all static methods and variables from hole.Hole into here.
it pulls in Depth and any other methods (including dig, so just calling this would work as well:
dig();
When the Hole class is loaded it first sets Depth to 3. But even before the constructor is called the static block sets Depth to 9. So that is why Depth would contain 9.

Ways of calling non static method from main in Java

We all know that we cannot call a non-static method from Java's static main method directly. I've written 2 ways to call non-static method from main (shown below).
What I wanted to ask is: Is there any significance difference between using code 1 and code 2 to overcome the limitation?
Code 1
public class Demo
{
public static void main(String[] args)
{
Demo demo = new Demo();
demo.printText();
}
public void printText()
{
System.out.println("Method successfully called.");
}
}
Code 2
public class Demo
{
public static void main(String[] args)
{
new Demo().printText();
}
public void printText()
{
System.out.println("Method successfully called.");
}
}
NOTE: In school, our professor told us "In Java, staticmethods of a class can be invoked through the name of the class in which they are defined, without having to instantiate an object of the class first."
But in code 2 no object was instantiated, yet I was able to call the non static-method?
There are 2 main things to be considered while using the first one over the second..
you will still have a reference to the Demo object, so you can call demo.someOtheMethod().
Your demo object will not be ready for Garbage collection as soon as printext() returns. i.e, it will not be ready until you actually exit main(). In the second case, it will be ready as soon as printext() returns..
The only difference is that you can reuse the value in the object demo later. However, you should not create an instance just to call such a method. The correct way to do this is to make the method static.
There is no any difference of executing code or the creating the object.
But in the second method, you don't have a reference to the object you created.(in first method, demo is the reference for the Demoobject) So you can't do any other thing with this object further, as there is no way of referencing it.
as example:
Suppose you had another method inside class Demo called foo1()
in first example you can run both method using a single object.
Demo demo = new Demo();
demo.printText();
demo.foo1();
but in the second method, You have to do it with 2 objects seperately.
new Demo().printText();
new Demo().foo1();
In Code1, you are creating an object using the class name as a reference variable, and calling that function and this would work very finely.
in code2, you are creating an anonymous object, which is basically used whenever we want to use the object only once in the lifecycle of the class.
In both code, the program will work finely.

Call main method in a JButton

I would like to know, how to call the main method as it is in a JButton into a JFrame with an action performed, i mean, just press Compare Button & execute the code from main class (Main class is separate from JFrame code).
public static void main(String[]args){
Comparative comp = new Comparative();
if(comp.loadComparative(args[0])){
comp.compareDbs();
comp.sendEmail();
}
}
private void CompareActionPerformed(java.awt.event.ActionEvent evt) {
?????????????
}
If the main class is on the classpath you can use reflection :
private void CompareActionPerformed(java.awt.event.ActionEvent evt) {
MyMainClassToCall.main(myArgs);
}
If the class is located elsewhere, likely in a jar, you can certainly use an URLClassLoader to load the class which contains the main method, then use
myMainClass.getMethod("main", String[].class).invoke(null, myArgs);
You can just get the arguments you need and then call it using the name of the class where it is:
MainClass.main(args);
To give a complete answer we actually need to know what's the name of the class that contains that main method. Also, I'm struggling to understand such a weird requirement but I'll do my best to come up with a useful answer.
To invoke your main method you need to access it through the class that contains it, since it's a static method. You also need to provide an array of arguments mainly because it seems that your main method is using the first of the elements in the arguments array. So something like this would work:
private void CompareActionPerformed(java.awt.event.ActionEvent evt) {
String[] args = new String[] { "myparam" };
MainClass.main(args);
}
Now, said that, let me note that such an invocation of a main method is a very bad practice, you could achieve the same copying the contents of your main method into your event handler CompareActionPerformed. Or even better, creating a separate and independent class with an static method that performs the same that you need from your main method. Then invoke that new static method from your main class and from your event handler (assuming that all the code is accessible from the same class loader).
I think it's a bad practice , you should follow some design pattern , like MVC or something , when JVM starts it looks for the "main" method and start from there , the thing you can do before calling main method is putting some code in a static braces like ...
public class test {
static {
some code
}
public static void main(String[] args){
}
}
this code will be executed before the main
There is just one class, it is Comparative inside it's all the code incluing the main....

Using methods from another class in the main?

Okay so I did search this question and a decent amount of results showed up. All of them seemed to have pretty different scenarios though and the solutions were different for each one so I'm a bit confused.
Basically, I have a Driver class that runs my program and contains the main method. I have a second class that has a few methods for editing a party (like party of characters in a game). What I wanted to do was this (part of main method)
System.out.println("Are you <ready> for your next battle? Or do you want to <edit> your party?");
Scanner readyScanner = new Scanner(System.in);
String readyString = readyScanner.next();
while(!readyString.equals("ready") && !readyString.equals("edit")) {
System.out.println("Error: Please input <ready> if you are ready for your next battle, or <edit> to change your party.");
readyScanner = new Scanner(System.in);
readyString = readyScanner.next();
}
if(readyString.equals("edit")) {
displayEditParty(playerParty, tempEnemy);
}
A lot of this is just some background code, the problem lies with
displayEditParty(playerParty, tempEnemy);
I get the error
Driver.java:283: cannot find symbol
symbol : method
displayEditParty(java.util.ArrayList<Character>,java.util.ArrayList<Character>)
location: class Driver
displayEditParty(playerParty, tempEnemy);
So, how could I call this method from another class in my main? In my code I use methods from other classes a few times, I'm a bit confused as to this one doesn't work.
You should make displayEditParty function public static and then you can use it in other class by className.displayEditParty(?,?);
Methods of class can be accessible by that class's object only. Check below code:
class A{
void methodA(){
//Some logic
}
public static void methodB(){
//Some logic
}
}
public static void main(String args[]){
A obj = new A();
obj.methodA(); // You can use methodA using Object only.
A.methodB(); // Whereas static method can be accessed by object as well as
obj.methodB(); // class name.
}
If your method is a static, you can call ClassName.methodName(arguments);
If your driver class not a static one you should create an instant of that class and call your method.
ClassName className=new ClassName();
className.displayEditParty(playerParty, tempEnemy);
I dont see where your declaring the Driver class in your code.
Driver foo = new Driver();
foo.displayEditParty(playerParty, tempEnemy);

Is it true that java.lang.Class object is created when the Java class is loaded, even before instantiation takes place?

Suppose the classes has code like this:
class C {
public static void show() {
}
}
class CTest {
public static void main (String[] args) {
C.show();
}
}
Then will it be perfectly legal to conclude that while referring to class C to access the static method show() here, behind the scene Java is actually calling the show() method through Java reflection ?
I.e. is it actually doing something like this
Class test = Class.forName(C);
test.show();
to call static methods?
If not, then how is it actually calling the static methods without creating objects?
If the above explanation is true, then how we'll justify the statement that "static members are only associated with classes, not objects" when we're actually invoking the method through a java.lang.Class object?
The JVM doesn't need to do anything like Class.forName() when calling a static method, because when the class that is calling the method is initialized (or when the method runs the first time, depending on where the static method call is), those other classes are looked up and a reference to the static method code is installed into the pool of data associated with that calling class. But at some point during that initialization, yes, the equivalent of Class.forName() is performed to find the other class.
This is a specious semantic argument. You could just as easily say that this reinforces the standard line that a static method is associated with the class rather than any instance of the class.
The JVM divides the memory it can use into different parts: one part where classes are stored, and one for the objects. (I think there might have been third part, but I am not quite sure about that right now).
Anyways, when an object is created, java looks up the corresponding class (like a blueprint) and creates a copy of it -> voila, we have an object. When a static method is called, the method of the class in the first part of the memory is executed, and not that of an object in the second part. (so there is no need to instantiate an object).
Besides, reflection needs a lot of resources, so using it to call static methods would considerably impact performance.
For extra info:
The called class will get loaded when it's first referenced by calling code.
i.e. The JVM only resolves and loads the class at the specific line of code that it first needs it.
You can verify this by using the JVM arg "-verbose:class" and stepping through with a debugger.
It will call ClassLoader.loadClass(String name) to load the class.
You can put a println statement into the ctor, to verify, whether it is called or not:
class C {
public static void show () {
System.out.println ("static: C.show ();");
}
public C () {
System.out.println ("C.ctor ();");
}
public void view () {
System.out.println ("c.view ();");
}
}
public class CTest
{
public static void main (String args[])
{
System.out.println ("static: ");
C.show ();
System.out.println ("object: ");
C c = new C ();
c.view ();
c.show (); // bad style, should be avoided
}
}

Categories