在这个java示例中使用Class而不是实际类型的原因?

时间:2010-01-12 23:03:24

标签: java awt

我已经看到过这个“设计模式”(不知道还有什么叫它..模板?)在Java代码中不止一次出现。预计申请将被延长并包括主要方法。我无法弄清楚在start方法中使用Class而不是AppFrame有什么好处,因为它只是类型转换为AppFrame的类型。这一切似乎都是毫无意义的,也许有人可以填补我。

public class Application {

 public static class AppPanel extends JPanel {
  //stuff
 }

 public static class AppFrame extends JFrame {
  protected AppPanel mainPanel;
  //more stuff
 }

 public static AppFrame start(Class appFrame) {
  try {

   final AppFrame frame = (AppFrame) appFrame.newInstance();
   java.awt.EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    frame.setVisible(true);
                }
            });
   return frame;
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
 }

 public static void main(String[] args){
  Application.start(AppFrame.class);
 }
}

3 个答案:

答案 0 :(得分:2)

我也见过这种情况,特别是在相当陈旧的例子中。

这个想法似乎是一切都以一个静态调用开始,用户不会在堆上创建任何东西。相反,“应用程序框架”以某种方式实例化它所需要的内容,并且用户仅指示要使用的具体实现。因此,用户指示要使用的类,但实际上还没有实例化。执行此操作的一个风险是您可以将其实例不可转换的类转移到AppFrame。这可能会导致异常。

我个人认为这个丑陋的设计。在通过类对象(如Smalltalk或Python)直接实例化类更常见的语言中,它是有意义的。在Java中,我认为坚持使用工厂接口更加笨拙而且更加OO。

答案 1 :(得分:2)

该模式称为type token,由Gilad Bracha创造并在Class Literals as Runtime-Type Tokens中讨论,以及mentioned here。实例化顶级容器JFrame是一种有趣的方法,但GUI组件应该在Event Dispatch Thread(EDT)上构建。根据构造函数中的//stuff以及start()的调用方式,它可以减轻escaped this的影响。

答案 2 :(得分:1)

start()的签名允许传递任何类,但实现将其限制为AppFrame的子节点,后者只是嵌套的静态类。由于所有内容都堆放在同一个文件中,我不知道为什么所有这些都是必要的,我同意 - 在这个特定的例子中实现它的方式毫无意义。