我有与Java相关的问题:
我想知道有没有办法通过使用变量创建类(在程序中)的路径。 我制作的程序将从某些网站下载图片并将其显示给用户。但是,不同的站点有不同的形式,这就是为什么我必须定义一系列特定于每个的功能。它们不能放在同一个类中,因为执行相同作业的函数(仅适用于另一个站点)必须具有相同的名称。我想尽可能简单地为其他网站添加支持。
无论如何,问题是,我是否可以使用变量调用程序中的函数来确定其位置。
例如:code.picturesite.functionINeed();
code
是包含所有编码的包,picturesite
不是类,而是包含所需类名称的变量 - 这样我只能将变量的值更改为调用不同的函数(或不同类中的相同函数)。
我真的不希望这是可能的(这更能让你理解问题的本质),但还有另一种方法可以做我想在这里实现的目标吗?
答案 0 :(得分:2)
是的,有办法。它被称为反射。
给定一个包含类名的String,你可以得到一个像这样的实例:
Class<?> c = Class.forName("com.foo.SomeClass");
Object o = c.newInstance(); // assuming there's a default constructor
如果没有默认构造函数,您可以通过c.getConstructor(param1.getClass(), param2.getClass(), etc)
给定包含方法名称和实例的String,您可以像这样调用该方法:
Method m = o.getClass().getMethod("someMethod", param1.getClass(), param2.getClass(), etc);
Object result = m.invoke(o, param1, param2, etc);
答案 1 :(得分:2)
我没有立即在你的问题中看到任何无法解决的问题,而不是让一个包含类名的变量,包含一个包含该类实例的变量 - 来调用类上的函数,您必须知道它实现了该功能,因此您可以将该功能放在接口中。
interface SiteThatCanFoo {
void foo();
}
和
class SiteA extends Site implements SiteThatCanFoo {
public void foo() {
System.out.println("Foo");
}
}
然后:
Site currentSite = getCurrentSite(); // or getSiteObjectForName(siteName), or similar
if (SiteThatCanFoo.isAssignableFrom(currentSite.class)) {
((SiteThatCanFoo)currentSite).foo();
}
答案 2 :(得分:1)
所以你想做这样的事情(检查ImageDownloader.getImageFrom
方法)
class SiteADownloader {
public static Image getImage(URI uri) {
System.out.println("invoking SiteADownloader on "+uri);
Image i = null;
// logic for dowlnoading image from siteA
return i;
}
}
class SiteBDownloader {
public static Image getImage(URI uri) {
System.out.println("invoking SiteBDownloader on "+uri);
Image i = null;
// logic for dowlnoading image from siteB
return i;
}
}
// MAIN CLASS
class ImageDownloader {
public static Image getImageFrom(String serverName, URI uri) {
Image i = null;
try {
// load class
Class<?> c = Class.forName(serverName + "Downloader");
// find method to dowload img
Method m = c.getDeclaredMethod("getImage", URI.class);
// invoke method and store result (method should be invoked on
// object, in case of static methods they are invoked on class
// object stored earlier in c reference
i = (Image) m.invoke(c, uri);
} catch (NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException | ClassNotFoundException e) {
e.printStackTrace();
}
return i;
}
// time for test
public static void main(String[] args) {
try {
Image img = ImageDownloader.getImageFrom("SiteB", new URI(
"adress"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}