有没有办法在运行时在 Java 中分配 Class?

Is there a way to assign the Class in Java at Runtime?

由于我现在正在重构我的代码,所以我试图首先找出可能的代码重复项。 作为一个可能的重复,我看到了两种基本上读取文件的方法:一种来自 FTP,另一种来自本地文件结构。问题是,他们当然使用不同的 类 来实现相同的事情。变量 directoryListing 是个棘手的问题。

readLogs(boolean useFTP){
// directory Listing of course needs to be of a different type here or not being declared at all 
    File[] directoryListing;
    File dir = Settings.getInputfolder();
    if(useFTP){
            // ftp implementation
            client = new FTPClient();               
            client.connect(Settings.getFtpHost());
            client.enterLocalPassiveMode();
            client.login(Settings.getFtpLoginname(), Settings.getFtpPassword());
            client.setFileType(FTPClient.BINARY_FILE_TYPE);

            //directoryListing should be of type FTPFile[] here
            directoryListing = client.listFiles(Settings.getInputfolder().toString());
    else{
        //directoryListing should be of type File[] in this case
        directoryListing = dir.listFiles();
    }
    if (directoryListing == null) {
            log.error("Input-folder not found:" + dir.getAbsolutePath());
    }
    //I want to be able to iterate - here myFolder might be of type File oder FTPFile
    for (Object myFolder : directoryListing) {
    ...
    ...
    }
}

我稍后在代码中使用的唯一方法在 File 和 FTPFile:
上具有完全相同的签名 getName()
isFile()
isDirectory()
列表文件()
我已经为那些使用了反射,例如

Method getFolderNameMethod = myFolder.getClass().getMethod("getName");
String name = (String) getFolderNameMethod.invoke(myFolder);

我可以用什么方法实现 directoryListing 变量的动态声明?

非常感谢您的宝贵时间和提前提出的建议! :D

我过去使用过 apache-commons-vfs:

http://commons.apache.org/proper/commons-vfs/

如果您不想添加一个库,您可以创建一个接口和它的 2 个实现,但是 VFS 将为您提供更多受支持的文件系统,并且在长期 运行 中可能更容易维护。

我确定还有其他人,但除了 apache 之外我从来不需要任何东西,所以我无法与他们交谈。

编辑:

根据您的评论,我会创建一个工厂,类似于:

public class FSFactory{
  public static IFSInteface getInterfaceFor(FSType t){
     if(FSType.FTP.equals(t)){
        return new FtpFileGetter();
     } else if (FSType.LOCAL.equals(t)){
        return new FSFileGetter();
     }
  }
}

代码未经测试,但我就是这样处理的。

使用策略和适配器模式:

首先定义公共接口

interface VirtualFile {
  /*
  getName()
  isFile()
  isDirectory()
  listFiles()
  */
}

然后创建两个适配器(一个用于文件,一个用于 FTPFile)

class FileAdapter implements VirtualFile {
  // delegates every method to the wrapped file
}

class FTPFileAdapter implements VirtualFile {
  // delegates every method to the wrapped ftp file
}

然后重构readLogs

readLogs(FileStrategy fileOrFtp){
  List<VirtualFile> directoryListing = fileOrFtp.listDirectory();
  for (VirtualFile myFolder : directoryListing) {
    ...
    ...
  }
}

interface FileStrategy {
  List<VirtualFile> listDirectory();
}

class FTPFileStrategy implements FileStrategy {
   // implement useFTP case (settings should be passed to the constructor
   // wrap each resulting FTPFile into a FTPFileAdapter
}

class LocalFileStrategy implements FileStrategy {
   // implement !useFTP case (settings, e.g. root folder should be passed to the constructor
   // wrap each resulting File into a FileAdapter
}

这样可以将所有问题分开,另外: - 没有如果了 - 没有铸造 - 没有反映 - 更短 methods/classes