Invoke java class static initialization via VM option - java

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.

Related

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.

Error of simple calculating process [duplicate]

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

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

Why are we allowed to have a final main method in java?

Can anyone tell me the use of making main method as final in java.
while this is allowed in java
public static final void main(String[] args) {
}
I dont see any use of making it final. anyways it is static so we can not override it.
Adding final to a static method can actually make a difference. Consider the following code:
class A {
public static void main(String[] args) {
System.out.println("A");
}
}
class B extends A {
public static void main(String[] args) {
System.out.println("B");
}
}
class C extends B {
}
public class Test {
public static void main(String[] args) {
C.main(args); // Will invoke B.main
}
}
Adding final to A.main would prevent accidental hiding of A.main. In other words, adding final to A.main guarantees that B.main is not allowed, and that C.main therefore prints "A" as opposed to for instance "B".
Why are we allowed to have a final main method in java?
Beside the above corner case, adding final to a static method doesn't make much difference, so I don't see a big point in adding a rule for disallowing it.
More information available here: Behaviour of final static method

Finding name of subclass running Main

I want to make a convenient super class that will make an instance of whatever subclass it is ran from, without having to hard-code the name of the sub class. What is the fastest way to do this?
We can assume that the subclasses' constructors will have same signature, e.g. no parameters.
class Main {
public static void main (String [] args) {
Main m = new NAME-OF-SUBCLASS();
}
}
class MainSub1 extends Main { /*...*/ }
class MainSub2 extends Main { /*...*/ }
So when invoking main from MainSub1 ($ java MainSub1 from the command line), a MainSub1 object is created, etc.
As I wrote this, i found this thread where the accepted answer says it can't be done, but of course it can, somehow, through reflection or something, right?
Not that I'd really recommend it, but there's a dirty trick to it:
class Main {
static Main m;
public static void main (String [] args) {
// use m
}
}
class MainSub1 extends Main { static { m = new MainSub1(); } }
class MainSub2 extends Main { static { m = new MainSub2(); } }
A serious answer would be to write a separate main for each subclass, but let it call a common inherited method that accepts an appropriate instance.

Categories