如果引用类在某些系统上不存在,如何编写java类

时间:2017-09-11 10:54:08

标签: java reflection

我有这种方法只能在Windows上运行并使用sun.awt.shell中的类,但是应用程序可以在非Windows系统上运行,而在Java上它可以与OpenSdk一起使用,我怀疑这不包括在内sun.awt.shell类。

我已从类中删除了sun.awt.shell import语句,因此只能在此方法中引用类名,并且我可以保证此方法永远不会在非Windows机器上运行。

但这是否足够或者无法在缺少这些类的系统上加载类,我是否需要重写方法以使用反射?

 public static boolean isRemote(String newPath)
    {
        try
        {
            Path root = Paths.get(newPath).getRoot();
            sun.awt.shell.ShellFolder shellFolder = sun.awt.shell.ShellFolder.getShellFolder(root.toFile());
            sun.awt.shell.ShellFolderColumnInfo[] cols = shellFolder.getFolderColumns();
            for (int i = 0; i < cols.length; i++)
            {
                if (cols[i].getTitle().equals(WINDOWS_SHELL_SIZE)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith("Network Drive"))
                {
                    return true;
                }
                else if (cols[i].getTitle().equals(WINDOWS_SHELL_ATTRIBUTES)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith("\\"))
                {
                    return true;
                }
            }
        }
        catch (Exception ex)
        {
            MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
            return false;
        }
        return false;
    }

2 个答案:

答案 0 :(得分:0)

  

但这是否足够,或者无法在缺少这些类的系统上加载类。

如果在运行时不存在类,则程序将失败。如果您使用的是编译引用,则通常会在启动时获得NoClassDefFoundError

  

我是否需要重写方法才能使用反射?

反思无济于事。如果您尝试使用Class.forName加载类(例如),如果该类不属于JRE,则会得到ClassNotFoundException

我不完全理解该代码实际上在做什么,但似乎使用的机制根本不适用于Linux系统(例如)。实际上,Linux系统上并没有一个明确定义的“远程”文件概念。

如果您解释了使用此方法的内容,也许会有所帮助。我怀疑,这只是在Windows上才有意义。

作为一般规则,您应该避免使用sun.*类,因为:    - 它们通常是特定于OS平台的,并且    - 他们可能会更改,或被删除,恕不另行通知。

我明白你现在在问什么。您实际上并不希望 1 isRemote在非Windows系统上工作。

有几种选择:

  • 您可以将该方法拆分为两部分,并使用动态类加载来加载系统特定部分。或者将isRemote方法作为动态加载的系统特定插件中的方法。 (基本上相同的想法......)在任何一种情况下,动态加载的类都可以使用普通的Java调用来调用ShellFolder

  • 您可以使用Class.forName("sun.awt.shell.ShellFolder")来(尝试)加载类,然后使用反射来调用它上面的方法。

但是,关于sun.*的说明仍然有效。 Sun / Oracle经常会更改或删除这些内部类。

1 - 或许你这样做,但是你会因为它不会这样做而辞职。

答案 1 :(得分:0)

我使用的解决方案只是将所有只需要在Windows上可用的类的方法放到一个类中。然后我在调用任何这些方法之前形成另一个类,总是检查以确保在Windows操作系统上运行

if(Platform.isWindows())
{
    return WindowsUtilsFS.isRemote(newPath)
}

因此,类永远不会被调用或加载。我已将其部署到Production中并且没有错误报告,所以我认为它正常工作。