I have got the following problem (I simplified it).
I programmed an abstract class, like this:
public abstract class Calculation{
abstract public int multiply(int x);
public final static void main(String[] args){
for(int i=0; i<args.length; i ){
int x = Integer.parseInt(args[i]);
// I want to call the Method multiply here.
// Therefore I need an object here!
}
}
}
My abstract class has a main-Method which should evaulate my args and then call the method multiply. Now I want to make some other classes like
public class MOne extends Calculation{
public int multiply(int x){
return x;
}
}
public class MTwo extends Calculation{
public int multiply(int x){
return 2*x;
}
}
public class MThree extends Calculation{
public int multiply(int x){
return 3*x;
}
}
If I call on the console:
java MOne 5
java MTwo 5
java MThree 5
I want java to print 5,10 and 15.
Sadly I don't know how to instanciate the MOne-class respectivly MTwo and MThree in the Calculation-class. Does anyone know, how to make it?
CodePudding user response:
It's possible but expensive because you have to search all classes on the classpath to find those that extend Calculation. A good tool for this is ClassGraph.
Try this code:
List<Class<Calculation>> calculations;
try (ScanResult scanResult = new ClassGraph().enableClassInfo().scan()) {
calculations = scanResult
.getSubclasses(Calculation.class.getName())
.loadClasses(Calculation.class);
}
for(Class<Calculation> calculation : calculations) {
Calculation calculationInstance = calculation.newInstance(); // needs null constructor
System.out.println("Java " calculation.getName() " " calculationInstance.multiply(5));
}
CodePudding user response:
Try this. You may need to find the equivalent to sun.java.command
for non-Oracle JVM.
public abstract class Calculation {
abstract public int multiply(int x);
public final static void main(String[] args)
throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
InstantiationException, NoSuchMethodException, SecurityException {
String className = System.getProperty("sun.java.command").split(" ")[0]; // Oracle JVM only
Class<?> loadedClass = Class.forName(className);
Method multiplyMethod = loadedClass.getMethod("multiply", int.class);
Object newInstance = loadedClass.newInstance();
for(int i=0; i<args.length; i ){
int x = Integer.parseInt(args[i]);
System.out.println("java " "className " multiplyMethod.invoke(newInstance, x));
}
}
Run it with the name of the inheriting class as the first argument and inheriting and base class on classpath:
java -cp path/to/jar;path/to/mine_class MOne 5