我想用main方法创建一个抽象类,以防止扩展它的开发人员必须实现main方法。我还想控制main方法中发生的事情。
我正在编写的抽象基类扩展了NanoHTTPD
,并通过调用ServerRunner.run()
启动服务器,参数是您要运行的类类型的类对象。
这是我到目前为止:
public abstract class FlexibleServer extends NanoHTTPD
{
public DeadSimpleMicroserver(int port)
{
super(port);
}
public static void main(String[] args)
{
ServerRunner.run(FlexibleServer.class);
}
}
问题是,由于这个类是抽象的,未来的开发人员将扩展类,所以我需要ServerRunner.run()
的参数作为子类的ACTUAL类型,所以我不能使用FlexibleServer.class
。
我尝试将参数更改为this.class,但后来我得到编译错误,“this”无法从静态上下文中引用(因为main()
是静态的)。
如何从main()
获取实际子类的类对象?
如果您要在运行时传递的类是动态的,则不能使用硬编码的类名称来调用它。您必须将调用更改为run
,以便将其传递给实际类的实例,或者您必须动态加载给定的类,例如main方法参数。
通过上述更改,您的问题得到解决。
例如,如果您正在动态加载类:
ServerRunner.run(Class.forName(args[0]));
假设将使用实际的类名调用应用程序。
替代方案包括重新设计代码,以便调用者传入类名,实例或类对象
我曾经工作过的框架有这样的基类,我们添加了这样的方法:
public abstract class FrameworkServer {
// framework stuff
protected static void main(String[] args, FrameworkServer instance) {
// parse args
// actually start the instance running
}
}
并且特定的服务器实例需要添加自己的main
方法,如下所示:
final class MyServer extends FrameworkServer {
public static void main(String[] args) {
main(args, new MyServer());
}
}
每个服务器都有一小部分样板,但这样可以避免反射并使代码更清晰。作为奖励,具体的子类现在可以将自己的参数添加到服务器的构造函数中,这对于单元测试通常非常有用。