Finding name of subclass running Main - java

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.

Related

Is it possible to access objects from another class without parameters

Is it possible to access an object created in one class from another class without using parameters/arguments?
For example:
public class Main {
public static void main(String[] args) {
Two make = new Two(); // Object I created.
make.ham();
}
}
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three {
public static void accessObject() {
// Can I access the object make here without parameters?
}
}
What I understood is that you want to access to make object, created inside Main class (Two make = new Two());. And yes, it's possible to do it.
You have to create your variable make as global and static (and it's recommended be public or protected, in case you have your classes in separate files).
So, inside your Main class, you will have to do something like:
public class Main {
public static Two make;
public static void main(String[] args) {
make = new Two(); // Object I created.
make.ham();
Three.accessObject();
}
}
As you can see, I created the make variable as static and global. This is necessary because your main method is static, and it's global to be able to be recognized by other classes. And to can call to accessObject method, I did it with the class name (because that method is static)(Three.accessObject();)
And finally inside your Three class, in the accessObject method it's necessary call to the static variable make from Main class:
class Three {
public static void accessObject() {
System.out.println("using make object from Main class in Three class...");
Main.make.ham();
}
}
As you can see now, I called the variable make with the name class Main because it's static, and finally, you will be able to call the ham method by this way.
You could you inheritance to solve your problem. For example, you would write:
class Three extends Two {
public static void accessObject() {
// You can now access the "Two" object since you have now made
// Three a subclass of Two.
}
}
EDIT:
If you wanted to say, change the implementation of the ham() method, you could do something like this:
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three extends Two {
#Override
public void ham() {
System.out.println("I'm inside ham, but inside the Three class.);
}
}

error on Implement interface in main class

Hi friends im learning java from basics..
I have some doubt in implementing interface.
WORKING CODE
Using interface in a class is working....
interface bala
{
void prnt();
}
class ex implements bala{
#Override
public void prnt() {
System.out.print("hi");
}
}
public class Solution
{
public static void main(String arg[])
{
ex p = new ex();
p.prnt();
}
}
NOT WORKING
Here is my doubt, why i cant implement interface in main method?
plea
interface bala
{
void prnt();
}
public class Solution implements bala
{
public static void main(String arg[])
{
prnt();
}
#Override
public void prnt() {
System.out.println("hi");
}
}
What is happening here?
Why implementing on main() is not working?
Is there is a way to make working interface on main function?
Given Bellow code works well.
interface bala
{
void prnt();
}
public class Solution implements bala
{
public static void main(String arg[])
{
Solution sol = new Solution();
sol.prnt();
}
public void prnt() {
System.out.println("hi");
}
}
It's not working, because you're trying to access non-static (i.e. instance) method from a static context.
In order to invoke it, you need an instance of the Solution class (note that in your working code you have an instance of the ex class, so here you need to do the same with slight difference):
Solution instance = new Solution();
instance.prnt();
Problem is main() is static, static blocks can access static members or with object reference . So here you could simply create an object/instance to invoke the method:
new Solution().prnt();
try new Solution().prnt() instead of calling prnt()
the problem is :
main method is a static method. And your overridden method is non-static. You can't call non-static methods from static context.
In order to call overridden method prnt() to call, you need to instantiate you Solution class like -
Solution sol = new Solution();
and then
sol.prnt();
Best Option to Do it . Create the instance of class and Access it.since main method is a static method you can do like that
Solution instance = new Solution();//Creating instance of class
instance.prnt();//access prnt .
You should create the object of Solution class in main method
Solution s1 = new Solution();
s1.print();
Otherwise, you can create the method as static because you are trying to access
the method from static context.

Why can I inherit final method from inner class?

I discovered that following code compiles:
class Ideone
{
public static void main (String[] args){
new Ideone().m();
}
final private void m(){
System.out.println("private final method");
}
class A extends Ideone{
public void method(String [] args){
m();
}
}
}
and executes.
I am very wondering about this.
Can you explain why does java designers(founders) made that it works?
A final method can be inherited by a sub class regardless the sub class is outside the parent class or inside the parent class. But you cannot override the final method in your subclass. If the final method is private you cannot inherit that in your subclass unless your subclass is inside the parent class (like in your example).
Since you declare the method private, then final has no effect and is redundant.
Overriding a private method don't really make much sense.
It is no different then calling a private method in a class from another method in the same class (which might be public). That is something that is done often to keep code more readable and method's manageable in size.
I don't think it is a stupid question :)
Take the Builder-pattern for example. It utilizes private constructors to make sure the class is constructed the correct way. So understanding what you have available in different scope's, and why is important :)
class Ideone {
private String m;
private Ideone(String m) {
System.out.println("Build me with: " + m);
this.m = m;
}
public String getM() {
return m;
}
static class IdeoneBuilder{
String m;
public IdeoneBuilder withM(String m) {
this.m = m;
return this;
}
public Ideone build() {
return new Ideone(this.m);
}
}
public static void main (String[] args){
// new Ideone(); // will not compile
Ideone ideone = new IdeoneBuilder()
.withM("test").build();
}
}
Edit: You can make the class Ideone final, and it will still work. And you are also making it impossible to subclass it. In other words, you make sure there is no other way to construct an object of your class other than using the builder (unless the use of reflection).

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.

Inheriting the main method

I want to define a base class that defines a main method that instantiates the class, and runs a method. There are a couple of problems though. Here is the base class:
public abstract class Strategy
{
abstract void execute(SoccerRobot robot);
public static void main(String args)
{
Strategy s = new /*Not sure what to put here*/();
s.execute(new SoccerRobot())
}
}
And here is an example derived class:
public class UselessStrategy
{
void execute(SoccerRobot robot)
{
System.out.println("I'm useless")
}
}
It defines a simple execute method, which should be called in a main method upon usage as a the main application. However, in order to do so, I need to instantiate the derived class from within the base class's main method. Which doesn't seem to be possible.
I'd rather not have to repeat the main method for every derived class, as it feels somewhat unnessary.
Is there a right way of doing this?
Move the main method out into a separate class. Separate concerns
Strategy (the name says it all)
Launcher (assembling components together and triggering execution)
public class Launcher
{
public static void main(String args)
{
Strategy s = new UselessStrategy();
//OR Strategy s = CreateInstance(args[0]) ;
//OR equiv mechanism for Dependency Injection if you don't want to hardcode the derived strategy to use.
s.execute(new SoccerRobot())
}
}
Static methods, such as "main", are not inherited but can be called directly. As a workaround, you could parameterize the class name as an argument to the main method:
public static void main(String args) throws Exception
{
String className = (args.length > 0) ? args[0] : 'UselessStrategy';
Strategy s = (Strategy) Class.forName(className).newInstance();
s.execute(new SoccerRobot())
}
If Class.forName is not possible, then maintaining a mapping of class names can provide a lookup table, per Andreas_D's comment:
private static Map<String, Class<? extends Strategy>> STRATEGY_NAME =
new HashMap<String, Class<? extends Strategy>>();
static {
STRATEGY_NAME.put("Useless", UselessStrategy.class);
STRATEGY_NAME.put("Better", BetterStrategy.class);
}
public static void main(String args[]) throws Exception {
String className = (args.length > 0) ? args[0] : null;
Class<? extends Strategy> klass = STRATEGY_NAME.get(className);
if (klass == null) klass = UselessStrategy.class;
Strategy s = klass.newInstance();
s.execute();
}
Automated methods for maintaining the mapping could be devised, such as using reflection, if the need arises.
You can define the class in a static block in the subclass.
public abstract class Strategy
{
protected static Class<? extends Strategy> instanceClass;
abstract void execute(SoccerRobot robot);
public static void main(String args)
{
Strategy s = instanceClass.newInstance()
s.execute(new SoccerRobot())
}
}
and then
public class UselessStrategy extends Strategy
{
static {
instanceClass = UselessStrategy.class;
}
void execute(SoccerRobot robot)
{
System.out.println("I'm useless")
}
}
You cannot instantiate an abstract class, but you definitely can instantiate a derived class from the base class. So just remove abstract from class definition
public class UselessStrategy
and do
Strategy s = new UselessStrategy();
I'd rethink this.
Put the code that you'd like executed somewhere else, preferably a non-static method, and call that. main() shouldn't be used this way.
I'd recommend creating a separate Strategy class in lieu of main.
Where is the main method called from? If it takes arguments then you can decide a concrete strategy based on those arguments, instantiate that strategy class and call the execute method on it.

Categories