当前位置: 首页 > 知识库问答 >
问题:

如何从String转换为基元类型或标准java Wrapper类型

於子晋
2023-03-14

我有一个< code > Java . lang . reflect . invocation handler ,我需要实现方法invoke()

我的精化中有一个类型为< code>java.lang.String的值,我需要将这个值转换成方法所期望的适当的returnType(它可以是一个像int、boolean、double这样的原语或者像Boolean、Integer、Double、Float等这样的包装类)。

例子:

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类型。

我(太)多次看到这样的事情,但我觉得不太合适:

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;
}

而且以上还不是我看到的最差的,到目前为止:)

这里有人有秘诀吗?

共有3个答案

劳仲渊
2023-03-14

大概org . Apache . commons . bean utils . convertutils能有帮助?

import org.apache.commons.beanutils.ConvertUtils;
// ...
final Object v = ConvertUtils.convert("42", Integer.class);
柳飞鸾
2023-03-14

我想我找到了什么

import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;

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

private Object convert(Class<?> targetType, String text) {
    PropertyEditor editor = PropertyEditorManager.findEditor(targetType);
    editor.setAsText(text);
    return editor.getValue();
}

我认为这3行代码比多个ifs更好,并且我避免添加外部库依赖项,因为java.beans包位于Java标准库内部(javadocs:

我觉得挺可以接受的;我唯一困惑的是< code>PropertyEditor包含在< code>java.beans包中,我更喜欢< code>java.util或< code>java.lang.reflect包中可用的内容,因为该代码实际上与< code>java.beans无关。

上面的代码还有一个优点,就是您可以注册额外的< code>PropertyEditor实例来翻译复杂的对象。不过,这并不是一件坏事。

我认为这比一系列如果要好,在美,但也在质量。

石苏燕
2023-03-14

据我所知,除了你提出的版本之外,没有真正的替代方案。您可以稍微简化一下(因为包装器类型都是< code>final),但是您基本上需要使用< code>if或< code>switch或散列来打开该类。

我的建议是像上面那样编码。丑陋的代码本身只是一个问题,如果你必须看它。所以把它放在一个实用程序方法里,不要再看它了。

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

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;
}

这样更简单,效率更高。它等同于原始版本,因为所有的类都是< code>final,并且规范声明< code>Class对象的相等性是对象标识。

可以说,我们应该使用< code >

我并不认为这不那么丑陋…但是“美”不是衡量代码质量的有用标准,因为它是主观的,也因为它没有告诉你代码是否易于理解和/或维护。

更新

为了支持基元类型,将相应的类添加到< code>if条件中;例如

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

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

 类似资料:
  • 问题内容: 我有一个,我需要实现方法invoke() 我从阐述中得到了一个类型值,我需要将该值转换为方法所期望的适当returnType(它可以是诸如int,boolean,double或wrapper类之类的原语,如Boolean,Integer,Double,Float等) 。 例: 我不希望简单地实现复杂对象之间的自动转换,但是我希望有一种简单的方法将String转换为标准Java类型。 我

  • 我有一个类型 现在我想做这样的事情。 如何将我的 转换为基元类型? 它给我的错误是: 将“Rating”类型转换为“number”类型可能是错误的,因为这两种类型都没有充分重叠。如果这是有意的,首先将表达式转换为“未知” 我已经经历过了,但我想要的是它的反面 编辑: tsconfig.json tsc版本:3.2.1

  • 我有以下代码来返回对象数组,对象数组中填充了基元类型的结构元素,我不知道如何将基元类型转换为jobject,然后使用SetObjectArrayElement方法设置为ObjectArray, 下面是我的C结构信息 我的JNI代码 写入核心转储失败。核心转储已被禁用。要启用核心转储,请在再次启动Java之前尝试“ulimit-c unlimited” 包含更多信息的错误报告文件保存为:/data1

  • 问题内容: 我想在一个程序包中打印所有的类名,并在每个程序包中打印相应的属性及其数据类型。 在一个代码中,我能够以字符串形式获取类名。在另一个代码中,我可以使用以下方法获取属性及其数据类型 但是我想合并两个代码。由于在第一个代码中我以字符串的形式获得了类名,我无法使用,因为这里是类型。 因此,我需要一种将“ 类名”从类型转换为类型的方法。 我试过了,但是没有用。 问题答案: 确保是完全合格的类名,

  • Rust 中有两种字符串类型:String 和 &str。 String 被存储为一个字节形式(Vec<u3>)的vector ,但确保一定是一个有效的 UTF-8 序列。String 是堆分配的,可增大且无上限。 &str 是一个指向有效 UTF-8 序列的切片(&[u8]),并可在用来查看 String 的内容,就如同 &[T] 是 Vec<T> 的全部或部分引用。(原文:&str is a

  • 在下面来自的语法中,泛型类型参数在实例化原始类型数组后用于类型转换,