如何从 String 转换为原始类型或标准 java Wrapper 类型

我有一个 java.lang.reflect.InvocationHandler 我需要实现方法 invoke()

I have a java.lang.reflect.InvocationHandler and I need to implement the method invoke()

我的详细说明中有一个 java.lang.String 类型的值,我需要将此值转换为该方法期望的适当 returnType(它可以是一个原始类型,如 int、boolean、double 或包装类,如 Boolean、Integer、Double、Float 等).

I have a value of type java.lang.String from my elaboration and I need to convert this value to the appropriate returnType expected by the method (it can be a primitive like int, boolean, double or wrapper classes like Boolean, Integer, Double, Float, etc).

例子:

public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable {
    String computedValue = compute(...);
    return convert(method.getReturnType(), computedValue);
}

private Object convert(Class<?> returnType, String stringValue) {
    return ...; // what's the simplest way?
}

我不希望简单地实现复杂对象之间的自动转换,但我希望有一种简单的方法来从 String 转换为标准 java 类型.

I am not expecting to simply implement an automatic conversion between complex objects, but I expect a simple way to convert from String to the standard java types.

我已经(太)见过很多次这样的东西,但它似乎不适合我:

I've seen (too) many times stuff like this, but it doesn't seem appropriate to me:

public static Object toObject( Class clazz, String value ) {
    if( Boolean.class.isAssignableFrom( clazz ) ) return Boolean.parseBoolean( value );
    if( Byte.class.isAssignableFrom( clazz ) ) return Byte.parseByte( value );
    if( Short.class.isAssignableFrom( clazz ) ) return Short.parseShort( value );
    if( Integer.class.isAssignableFrom( clazz ) ) return Integer.parseInteger( value );
    if( Long.class.isAssignableFrom( clazz ) ) return Long.parseLong( value );
    if( Float.class.isAssignableFrom( clazz ) ) return Float.parseFloat( value );
    if( Double.class.isAssignableFrom( clazz ) ) return Double.parseDouble( value );
    return value;
}

到目前为止,以上还不是我看到的最糟糕的一个:)

and the above is not even the worse one I saw, so far :)

这里有什么秘诀吗?

推荐答案

据我所知,您提供的版本没有真正的替代方案.您可以稍微简化一下(因为包装器类型都是 final),但您本质上需要使用 ifswitch 或散列来切换在课堂上.

As far as I'm aware, there is no real alternative to the version you presented. You can simplify it a bit (since the wrapper types are all final), but you essentially need to use if or switch or hashing to switch on the class.

我的建议是像上面那样编写代码.丑陋的代码本身只是一个问题,如果你不得不看的话.所以把它放在一个实用方法中,不要再看它了.

My advice is to code it like the above. Ugly code is only a problem per se if you have to look at it. So put it inside a utility method and don't look at it again.

FWIW - 这是我简化方法的方式:

FWIW - this is how I'd simplify the method:

public static Object toObject( Class clazz, String value ) {
    if( Boolean.class == clazz ) return Boolean.parseBoolean( value );
    if( Byte.class == clazz ) return Byte.parseByte( value );
    if( Short.class == clazz ) return Short.parseShort( value );
    if( Integer.class == clazz ) return Integer.parseInt( value );
    if( Long.class == clazz ) return Long.parseLong( value );
    if( Float.class == clazz ) return Float.parseFloat( value );
    if( Double.class == clazz ) return Double.parseDouble( value );
    return value;
}

这样更简单、更高效.并且它等同于原始版本,因为类都是 final 并且因为规范声明 Class 对象的相等性是对象身份.

This is simpler and more efficient. And it is equivalent to the original version because the classes are all final and because the specs state that equality for Class objects is object identity.

可以说,我们应该使用直接返回包装器对象的 <wrapper>.valueOf(String) 方法.

Arguably, we should be using the <wrapper>.valueOf(String) methods which return the wrapper objects directly.

我并没有声称这不那么丑……但是美"并不是衡量代码质量的有用指标,因为它是主观的,因为它不能告诉您代码是否易于理解和/或维护.

I make no claim that this is less ugly ... but "beauty" is not a useful measure of code quality, because it is subjective and because it doesn't tell you whether the code is easy to understand and / or maintain.

更新

为了也支持原始类型,将相应的类添加到 if 条件中;例如

To support primitive types as well, add the corresponding classes to the if conditions; e.g.

    if (Boolean.class == clazz || Boolean.TYPE == clazz) {
        return Boolean.parseBoolean(value);
    }

现在可能已经到了在类型名称上进行 String 切换更有效的地步,尽管需要考虑一些稍微棘手的类型标识问题.(理论上,您可以拥有由不同类加载器加载的具有相同全名的多个类型.我认为您需要在类加载器中快速而松散地"使用原始包装类来做到这一点......但是我认为这仍然是可能的.)

It may now be getting to the point where doing a String switch on the type's name is more efficient, though there are some slightly knotty issues of type identity that need to be thought through. (In theory, you can have multiple types with the same full name that have been loaded by different classloaders. I think you'd need to "play fast and loose" in a classloader to do that with the primitive wrapper classes ... but I think it might still be possible.)

相关文章