从变量定义的类中读取

时间:2012-06-01 12:52:26

标签: java

我有与Java相关的问题:

我想知道有没有办法通过使用变量创建类(在程序中)的路径。 我制作的程序将从某些网站下载图片并将其显示给用户。但是,不同的站点有不同的形式,这就是为什么我必须定义一系列特定于每个的功能。它们不能放在同一个类中,因为执行相同作业的函数(仅适用于另一个站点)必须具有相同的名称。我想尽可能简单地为其他网站添加支持。

无论如何,问题是,我是否可以使用变量调用程序中的函数来确定其位置。

例如:code.picturesite.functionINeed();

code是包含所有编码的包,picturesite不是类,而是包含所需类名称的变量 - 这样我只能将变量的值更改为调用不同的函数(或不同类中的相同函数)。

我真的不希望这是可能的(这更能让你理解问题的本质),但还有另一种方法可以做我想在这里实现的目标吗?

3 个答案:

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