我有一个名为Trader
的抽象类,它的作用类似于带有服务器的客户端(StockMarket),我想在Trader类中声明,所有从它继承的类都需要实现一个主入口点,以便它们可以运行。
问题是,如果我写:
public static abstract void main(String[] args) throws Exception;
它给出一个错误,只允许可见性修饰符。但是如果我删除静态修饰符,那么它就不能作为允许它运行的主要入口点。
那么如何声明一个抽象类的所有子类都必须实现一个main方法呢?
你不能。
相反,我要做的是在 Trader 中声明一个抽象的非静态方法:
public abstract void run(String[] args) throws Exception;
然后声明一个单独的主类来实例化一个实例,并调用 run 方法:
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
}
}
}
让我们从
public static void main (String[] args)...
静态的
表示此方法确实需要类的实例(包含此方法)。Java 虚拟机 (JVM) 将此声明为程序入口点的要求,原因是该类可能有多个构造函数或没有默认构造函数,并且 JVM 无法知道如何创建该类的对象。
公共
允许该方法在包(显然和类)之外可访问,因此 JVM 可以自由调用此方法。
主要
是 JVM 在类中查找的方法的名称,因为可能有多个公共静态方法。
无效
不返回任何内容。这是 JVM 查找作为入口点的签名部分。
现在让我们根据这些信息回答您的问题。多态性与 OOP 的继承和接口实现概念相关,与静态方法无关。
所以你唯一的选择就是根据"args"选择 1 个"公共静态 void main"方法作为入口点,调用其他公共静态方法。但是,其他方法不需要具有相同的签名。
静态方法不能是抽象的。
- 静态成员数据对于所有对象和派生类都是相同的。
- 派生类不能重写静态成员。
由于抽象方法需要在派生类中定义,因此它不能是静态的。 删除静态并尝试。
>static
方法不支持多态性,因此不能将其声明为abstract
。 但是你可以用@MauricePerry提出的抽象方法来声明一个抽象类。我会想出如何获得主类?
您可以从系统属性中提取主类名sun.java.command
。
- 从命令中截断参数。
- 其次,截断 IDE 主类名(如果存在)。
这是我可以使用的实现:
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;
}
}
例
public class Application extends Trader {
@Override
protected void run(String... args) {
System.out.println("Application");
}
}
使用命令java Application
运行Application
或在 IDE 中运行它。
要运行程序 JVM,请查找 main 方法,例如 公共静态空隙主(字符串[] 参数) 摘要不与主方法一起使用