有没有办法在运行时在 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
由于我现在正在重构我的代码,所以我试图首先找出可能的代码重复项。 作为一个可能的重复,我看到了两种基本上读取文件的方法:一种来自 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