Error of simple calculating process [duplicate] - java

I've learnt that the only public class in a Java file must also have the main method. However, below you can see the main method inside an inner class instead?
What is the rule with regard to the main method definition in a source file?
public class TestBed {
public TestBed() {
System.out.println("Test bed c'tor");
}
#SuppressWarnings("unused")
private static class Tester {
public static void main(String[] args) {
TestBed tb = new TestBed();
tb.f();
}
}
void f() {
System.out.println("TestBed::f()");
}
}

If you want to start a class with java (the Java launcher: java test.MyClass) then this class must have a main method with the well known signature.
You can have a main method with the same signature anywhere you want. But don't expect that the launcher will find it.
P.S. The name of the language is Java, not JAVA.
There is a minor detail:
You may do this:
package test;
public class Test {
/**
* #param args the command line arguments
*/
static public class A {
public static void main(String[] args) {
System.err.println("hi");
}
}
}
java test.Test$A
but this is non standard ...

Any class that can have a static method can have a public static void main(String[] args).
This includes:
top-level classes (whether public or not), e.g.
public class Foo {
public static void main(String[] args) {
System.out.println("Hello");
}
}
and inner static classes (whether public or not) (like your example).
It does not include:
anonymous classes
inner non-static classes
So both of these are illegal:
public class Foo {
private Object bar = new Object() {
public static void main(String[] args) {
System.out.println("Hello");
}
};
}
public class Foo {
private class Bar {
public static void main(String[] args) {
System.out.println("Hello");
}
};
}

Every Java application must have a main method. It’s the starting point for the execution of the code in the application. Its method signature is:
public static void main(String[] args)
A static inner class is a class that is defined inside of a different class's definition and marked as being static.
For example, if the outer class is named TestBed, then an inner class of TestBed, which is named Tester, would be compiled into TestBed$Tester.class. The separation of .class files means that you can keep the supplemental, nested code tightly coupled to the primary, outer class.
They are in the same source file, and the inner class is actually inside the outer class. All that and you don't have to pay any sort of deployment or run time cost.
By using static inner classes, you can add additional support functionality to your systems for capabilities such as testing, while incurring no penalties in normal, production deployment.
To execute the main() method of that TestBed.Tester class,
% java TestBed$Tester

This is interesting as the code will compile and run in Eclipse, but will just compile from using commmand line. When you run from eclipse it will find the static main method from within the inner class and run it.
But when running java TestBed from the command line you will get error - Exception in thread "main" java.lang.NoSuchMethodError: main which is a valid error as you have not defined your main method in main class.
Why would you want to define your main method in an inner class? Your main method should be defined in public class, this is not a rule but common practice.
In below code I've moved the main method into outer class which works both in Eclipse & command line :
public class TestBed {
public TestBed() {
System.out.println("Test bed c'tor");
}
#SuppressWarnings("unused")
private static class Tester {
}
public static void main(String[] args) {
TestBed tb = new TestBed();
tb.f();
}
void f() {
System.out.println("TestBed::f()");
}
}

Related

Why is the Jshell not executing Methods cotaining Enum fields?

I have a simple Class. Zelle is a simple Enum.
public class Main {
public void getZelle (){
System.out.println(Zelle.RED);
}
public static void test(){
System.out.println(Zelle.Empty);
}
public static void main(String[] args) {
System.out.println("HEllo World");
}
}
If i want to open these Methods with the Jshell i get the following Errors which I do not understand:
jshell> Main.getZelle()
| Error:
| non-static method getZelle() cannot be referenced from a static context
| Main.getZelle()
| ^-----------^
jshell> Main.test()
| attempted to use class Main which cannot be instantiated or its methods invoked until variable Zelle is declared
jshell> Main.main(new String[0])
| attempted to use class Main which cannot be instantiated or its methods invoked until variable Zelle is declared
But if I run the main() in the IDE it will print my test() Method
public static void main(String[] args) {
test();
}
You are accessing the non-static methods in a static way. You can call the non-static methods by creating an object of your class. Your code will look like this:
public class Main {
public void getZelle (){
System.out.println(Zelle.RED);
}
public static void test(){
System.out.println(Zelle.Empty);
}
public static void main(String[] args) {
System.out.println("HEllo World");
Main main=new Main(); // this is the way to create an o object
main.getZelle(); //this is how you call a non-static method using class reference
main.getTest();
}
}
Main.getZelle()
You are trying to call method getZelle() as a static method – which it is not – hence the error message because getZelle() is not a static method.
Main.test()
test() is a static method, however it references Zelle (which you claim is an enum but you did not post its definition) and JShell does not know how to find that enum, hence the error message. JShell is trying to compile your class Main but it cannot since Main references Zelle and JShell cannot find the definition of Zelle.
Main.main(new String[0])
Same problem as with Main.test().
Since I couldn't find the definition of Zelle in your question, I guessed what it is and added it to the code that you enter into JShell via its editor. The code is below.
enum Zelle {
Empty, RED
}
public class Main {
public void getZelle (){
System.out.println(Zelle.RED);
}
public static void test(){
System.out.println(Zelle.Empty);
}
public static void main(String[] args) {
System.out.println("HEllo World");
}
}
Now when I enter Main.main(new String[0]) into JShell, the code executes and I get no error messages. Note, however, that Main.getZelle() will still cause an error because getZelle() is not a static method (as I explained above).
I also recommend that you adopt Java naming conventions. Empty should be EMPTY.
You should declare your enum Zelle and create instance of Main class to call non-static methods:
enum Zelle {
RED, Empty
}
final var main = new Main();
main.getZelle(); // RED
Main.test(); // Empty
Main.main(new String[0]); // HEllo World
You need to import the Enum into the JShell with jshell Nameofenum.java.

How to fix the issue in the below code snippet

I am implementing the method hiding concept through inheritance.I am getting the error.
class Parent
{
synchronized strictfp final static public void main(String...ab)
{
System.out.println("Hello,Java is better than C++");
}
}
class Child extends Parent {
static public void main(String[] args)
{
System.out.println("Hello, C++ is better than Java");
}
}
I am executing the program as Parent.java
javac Parent.java
Expected
Two classes should get created
1.Parent.class 2.Child.class
java Parent
Hello,Java is better than C++
java Child
Hello, C++ is better than Java
Actual
javac Parent.java
Parent.java:11: error: main(String[]) in Child cannot override main(String...) in Parent
static public void main(String[] args)
^
overridden method is static,final
1 error
You have to remove final word from Parent class declaration.
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206822805-What-is-the-point-of-the-static-method-declared-final-inspection-
When you make a method as final then that method cannot be overridden in any class. So you need to remove the keyword final.
class Parent
{
synchronized strictfp static public void main(String...ab)
{
System.out.println("Hello,Java is better than C++");
}
}
class Child extends Parent {
static public void main(String[] args)
{
System.out.println("Hello, C++ is better than Java");
}
}

In java constructor and main which one will execute first?

Basically which one will execute first the main method or the constructor?
public class ConstructorExp {
public ConstructorExp() {
System.out.println("Ctt");
}
public static void main(String[] args) {
System.out.println("Inside Main Methos");
System.out.println("Main");
}
}
The main method will always be excecuted first, because it is a special static method that will be called from Java itself to start an application.
For more about the main method please read Java main() Method Explained for example.
Constructors will be created on object creation - in your case no object creation happens - so the constructor will never be executed.
You could modify your example to also execute the constructor:
public class ConstructorExp {
public ConstructorExp() {
System.out.println("Ctt");
}
public static void main(String[] args) {
System.out.println("Inside Main Methos");
ConstructorExp example = new ConstructorExp();
System.out.println("Main");
}
}
Be carefully, because the example object is never used the constructor call might be eliminated by some kind of optimization depending on the compiler you are using.

How can you declare that all subclasses of an abstract class will implement main?

I have an abstract class called Trader which acts like a client with a server (StockMarket) and I would like to declare in the Trader class that all classes that inherit from it will need to implement a main entry point so that they can be run.
The problem is that if I write:
public static abstract void main(String[] args) throws Exception;
it gives an error that only visibility modifiers are allowed. But if I remove the static modifier then it does not work as a main entry point allowing it to be run.
So how to declare all subclasses of an abstract class must implement a main method?
You can't.
What I would do instead is declare an abstract, non-static method in Trader:
public abstract void run(String[] args) throws Exception;
And then declare a separate main class that would instantiate an instance, and call the run method:
class RunTrader {
private static final String DEFAULT_CLASS = "...";
public static void main(String[] args) {
try {
String className = System.getProperty("main-trader-class", DEFAULT_CLASS);
Class<Trader> traderClass = (Class<Trader>)Class.forName(className);
Trader trader = traderClass.newInstance();
trader.run(args);
} catch (Exception e) {
// handle the exception
}
}
}
Lets start with the meaning of
public static void main (String[] args)...
static
means that this method does require an instance of the class (containing this method). Java virtual machine (JVM) states this as a requirement for the entry point of a program, reason being that the class may have multiple constructors or no default constructor and there is no way for JVM to know how to create object of the class.
public
allows the method to be accessible outside the package (and class obviously), so JVM is free to invoke this method.
main
is the name of the method that JVM looks for in the class, since there could be multiple public static methods.
void
returns nothing. This is the part of the signature that JVM looks for as entry point.
Now lets answer your question in light of this information. Polymorphism is relevant to OOP concept of inheritance and interface implementation, and it irrelevant to static methods.
So the only choice you have is to choose 1 'public static void main' method as the entry point based on the 'args', call other public static methods. However, other methods need not have the same signature.
Static methods cannot be abstract.
Static members data are same for all the objects and derived classes.
Static members can't be overridden by derived class.
Since abstract method need to be defined in derived class it can't be static.
Remove static and try.
static method does not supports polymorphism, so you can't declare it as abstract. but you can declaring an abstract class with abstract methods that #MauricePerry has been proposed. I will come up with how to get the Main class?
you can extract the Main class name from the system property sun.java.command.
truncate the args from the command.
second, truncate the IDE Main class name if present.
here is my implementation you can using:
public abstract class Trader {
protected abstract void run(String... args);
public static void main(String[] args) throws Exception {
runAs(getMainClass(args)).run(args);
}
private static Trader runAs(Class<?> mainClass)
throws IllegalAccessException, InstantiationException {
checking(!Modifier.isAbstract(mainClass.getModifiers())
, () -> "abstract class can't be run: " + mainClass);
checking(Trader.class.isAssignableFrom(mainClass)
, () -> "class is not a " + Trader.class
+ " can't be run: " + mainClass);
return Trader.class.cast(mainClass.newInstance());
}
private static void checking(boolean condition, Supplier<String> message) {
if (!condition) {
throw new IllegalArgumentException(message.get());
}
}
private static Class<?> getMainClass(String... args)
throws ClassNotFoundException {
String command = commandWithoutArgs(args);
String[] classes = command.split("\\s+");
return Class.forName(classes[ classes.length - 1]);
}
private static String commandWithoutArgs(String[] args) {
String command = System.getProperty("sun.java.command");
return command.substring(0, command.length() - argsLength(args)).trim();
}
private static int argsLength(String[] args) {
if (args.length == 0) {
return 0;
}
return Stream.of(args).collect(Collectors.joining(" ")).length() + 1;
}
}
Example
public class Application extends Trader {
#Override
protected void run(String... args) {
System.out.println("Application");
}
}
run the Application using command java Application or run it in IDE.
To run a program JVM find main method like
public static void main(String[] args)
abstract is not used with main method

Invoke java class static initialization via VM option

Is there any way to force static initialization of some class B before entering the main() method of class A, without changing class A, using only VM options?
I'm not aware of any way to do it without code. In code it's easy of course.
public class C {
static {
// Fetch and throw away an instance of B to make sure it is loaded
B.getInstance();
}
static void main(String[] args) {
// Do stuff, B is initialized
A.main(args);
}
}
In fact you could just do
public class C {
static void main(String[] args) {
B.getInstance();
A.main(args);
}
}
Your request doesn't make a lot of sense though. Ask a question about the problem you are trying to solve by doing this and you will hopefully get a much more useful answer.
you could create a class that initializes other classes and then calls the real main method, e.g:
public static void main(String[] args) throws Exception {
Class<?> mainClass = Class.forName(System.getProperty("mainClass"));
for (String className : System.getProperty("initClasses").split(";")) {
Class.forName(className);
}
Method main = mainClass.getMethod("main", String[].class);
main.invoke(null, new Object[] { args });
}
Then you would start the application with that class as the main class and specify the real main class and the classes to be initialized via properties.

Categories