将String转换为任何所需类的通用代码

时间:2012-01-30 16:18:35

标签: java generics design-patterns reflection

我需要编写一个方法,例如:

MyClassObject convert(Class MyClass , String value)

转换方法的工作是将String转换为MyClass的对象,其中MyClass可以是任何东西(原始除外) - 整数,布尔,字符,日期......这里的可能性很大 - 这就是我的原因放弃我愚蠢的if-else块来单独处理所有案件。

我可以看到与C#相关的内容(不知道它是否有效),不知道我们是否有this的Java等价物或this

我理解不是所有内容都可以从字符串转换,我准备处理非可解析项的异常。

我不知道这是否可行。如果没有,请帮助我为我的代码设计合适的设计模式。

谢谢!

2 个答案:

答案 0 :(得分:3)

你最好的选择可能是ServiceLoader机制。这允许您定义一对接口,例如:

interface StringConverterProvider{
    StringConverter<T> getConverterFor(Class<T> clazz);
}

interface StringConverter<T>{
    T convert(String s);
}

...然后在运行时找到这些接口的所有实现,如下所示:

ServiceLoader<StringConverterProvider> converterProviderLoader
    = ServiceLoader.load(StringConverterProvider.class);

T convert(String s, Class<T> t){
    for(StringConverterProvider scProv : converterProviderLoader){
        StringConverter<T> converter = scProv.getConverterFor(t);
        if (converter != null)
            return converter.convert(s);
        }
    return null;
}

通过将ServiceLoader文件中的META-INF目录中的特殊文件列为jar,可以使接口的实现可用于{{1}}。有关详细信息,请参阅javadoc。

答案 1 :(得分:2)

使用反射并希望基元的所有包装器对象都包含一个带有字符串参数值的构造函数,您可以像以下一样实现此目的

// A sample test with main
public static void main(String[] args) {
    Object obj = create(Integer.class, "54896");
    Integer val = (Integer) obj;
    System.out.println(val);
}

// Method to create the desired object with the given value
private static Object create(Class myClass, String value) {
    Object obj = null;
    try {
        Constructor constructor = myClass.getConstructor(new Class[]{String.class});
        obj=constructor.newInstance(value);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return obj;
}