简体   繁体   English

有没有一种方法可以在运行时用Java分配类?

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

Since I am refactoring my code right now, I am trying to first sort out possible code duplicates. 由于我现在正在重构代码,因此我试图首先找出可能的代码重复项。 As a posible duplicate I see the 2 methods which basically read files: One from FTP and another from local filestructures. 作为可能的重复,我看到了两种基本读取文件的方法:一种是从FTP读取的,另一种是从本地文件结构读取的。 The problem is, that they of course use different classes to achieve the same things. 问题是,他们当然使用不同的类来实现相同的目的。 The variable directoryListing is the tricky one. 变量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) {
    ...
    ...
    }
}

The only methods I am using later on in the code have the exact same signatures on both File and FTPFile: 我稍后在代码中使用的唯一方法在File和FTPFile上都具有完全相同的签名:
getName() getName()
isFile() isFile()
isDirectory() isDirectory()
listFiles() listFiles()
I have used reflections for those eg 我对那些使用了反思

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

In what way can I achieve a somewhat dynamic declaration of the directoryListing variable? 我可以通过什么方式实现directoryListing变量的某种动态声明?

Thank you very much for your time and advice in advance! 非常感谢您的时间和事先的建议! :D :D

I have used apache-commons-vfs in the past: 我过去曾经使用过apache-commons-vfs:

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

If you don't want to ad a lib, you could create an interface and 2 implementations of it, but VFS will give you more supported filesystems and probably be easier to maintain in the long run. 如果您不想添加一个库,则可以创建一个接口及其2个实现,但是VFS将为您提供更多受支持的文件系统,并且从长远来看可能更易于维护。

I'm sure there are others, but I've never needed anything other than the apache one so I can't speak to them. 我敢肯定还有其他人,但是除了apache以外,我什么都不需要,所以我不能和他们说话。

Edit: 编辑:

Based on your comment, I'd crate a factory, something like: 根据您的评论,我将创建一个工厂,例如:

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();
     }
  }
}

The code is not tested, but this is how I handle stuff like this. 该代码未经测试,但这就是我处理此类内容的方式。

Use Strategy and Adapter pattern: 使用策略和适配器模式:

First define the common interface 首先定义通用接口

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

then create two adapter (one for File, one for FTPFile) 然后创建两个适配器(一个用于File,一个用于FTPFile)

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

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

Then refactor readLogs : 然后重构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
}

This keeps all concerns separated and additionally: - no ifs any more - no casting - no reflection - shorter methods/classes 这使所有关注点分离开来,并且另外:-没有更多的东西-没有强制转换-没有反射-较短的方法/类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM