在运行时动态加载类

时间:2013-11-29 17:51:31

标签: java

我正在为Windows和Mac OSX开发Java应用程序。有一些与平台相关的代码片段。应用程序将在运行时建立平台,然后执行正确的代码,而不是将源代码拆分为两个单独的分支。

这有点像魅力。但我现在使用的代码只能在运行Mac OSX的计算机上执行:

package abc.extension;

import com.apple.eawt.Application;
import abc.Globals;

public class osx {
    public static void setApplicationLook() {
        Application application = Application.getApplication();
        application.setDockIconImage(Globals.iconImage);
    }
}

以上代码完美无缺。但是,当它导入仅在Mac OSX上可用的类时,该应用程序将无法在其他平台上编译或运行。

我认为解决方案是在函数com.apple.eawt.Application中动态导入setApplicationLook()。 由于该功能仅在运行Mac OSX的计算机上调用,因此不会在其他平台上引发任何错误。

但是怎么会这样做呢?

3 个答案:

答案 0 :(得分:2)

你可以;

  • 确保编译程序时编译所需的每个类都可用,无论您使用的是什么平台还是
  • 使用反射库来调用方法,因此它不需要在编译时可用。

使用反射代替你可以

// import com.apple.eawt.Application;
Class applicationClass = Class.forName("com.apple.eawt.Application"):

// Application application = Application.getApplication();
Object application = applicationClass.getMethod("getApplication()")
                                     .invoke(null); // static method.

// application.setDockIconImage(Globals.iconImage);
appplicationClass.getMethod("setDockIconImage", Image.class)
                 .invoke(application, Globals.iconImage);

答案 1 :(得分:1)

如果您想避免反射,则在specs

中定义类加载行为
  
      
  • T是一个类,创建了一个T实例。
  •   
  • T是一个类,调用T声明的静态方法。
  •   
  • 分配由T声明的静态字段。
  •   
  • 使用由T声明的静态字段,该字段不是常量变量(§4.12.4)。
  •   
  • T是顶级类(第7.6节),并且执行在词典内嵌套在T(第8.1.3节)内的断言语句(第14.10节)。
  •   
     

...

     

在任何其他情况下,不会初始化类或接口。

只要你在编译时拥有Mac库(甚至是存根),除非你在使用它们的类中执行方法,否则你不必担心它们是否在运行时有它们。

答案 2 :(得分:0)

尝试了一下getMethod和随机代码的组合,但我到了那里。

public static void setApplicationLook() {
    Class aClass = classLoader.loadClass("com.apple.eawt.Application");
    Method getApplication = aClass.getMethod("getApplication", null);
    Object application = getApplication.invoke(null);
    Method setDockIconImage = aClass.getMethod("setDockIconImage", Image.class);
    setDockIconImage.invoke(application, Globals.iconImage);
}