我有这种方法只能在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;
}
答案 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中并且没有错误报告,所以我认为它正常工作。