【问题标题】:Dynamically casting to primitives in Java在 Java 中动态转换为原语
【发布时间】:2010-12-12 09:04:45
【问题描述】:

编辑:这已经解决了。感谢所有帮助过的人。在将对象转换为正确的包装类后调用该方法。但是 String.valueOf() 实现同样的效果要简单得多。

你好--

我正在尝试做的事情甚至可能是不可能的。我现在已经花了几个小时研究和试验各种东西,所以我想我最终会四处打听,看看是否有人知道这是否可能。

是否可以使用反射将未知类型的原始类型的包装器动态转换为原始类型?

我基本上是在尝试创建一个通用的 toString 函数,它可以处理任何类型的原语到字符串的转换。这样一个看似简单的事情却是令人沮丧的困难(我知道我可以测试每种类型以查看它是否属于 Wrapper.class 类型并专门对其进行转换,但此时我只是出于固执而追求这一点)。

以下会引发 ClassCastException。 primClass 类似乎是正确的(打印 primClass.getName() 时给出“int”)。

    private String toString(Number obj){
    String result = "";
    try{
        Class objClass = obj.getClass();
        Field field = objClass.getDeclaredField("TYPE");
        Class primClass = (Class)field.get(obj);
        Method method = objClass.getMethod("toString", new Class[]{primClass});
        Object args = new Object[]{primClass.cast(obj)};
        result = (String)method.invoke(null, args);
    }catch(Exception ex){
        //Unknown exception. Send to handler.
        handleException(ex);
    }
    return result;
}

所以我有点不知所措,真的。有人有想法么?任何帮助将不胜感激。

【问题讨论】:

  • toString Double, Long, ... 上的方法不符合您的要求?

标签: java reflection dynamic casting primitive


【解决方案1】:

也许我遗漏了什么,但obj.toString() 可以。

如果您查看实现,它会调用String.valueOf(value),而后者又会调用Double.toString(..)Long.toString(..) 或其他任何东西。因此,调用toString() 会自动调用所需的方法。没有你的任何反映。

【讨论】:

    【解决方案2】:

    您可能想看看Apache Commons Lang,尤其是ToStringBuilder.reflectionToString()。即使您不想仅为 toString() 引入依赖项,它也是开源的,因此您可以查看实现。

    method.invoke 接受 Wrapper 类型而不是 primivtes 类型。

    【讨论】:

    • 哦。拉屎。我不敢相信。我以为我已经尝试过了,但它没有用,但我一定只是尝试使用包装类找到方法,而不是调用它。我决定确定一下,它奏效了。我现在觉得自己很傻。非常感谢。
    【解决方案3】:

    也许你的问题有一些我不明白的地方,但对于原始的,你可以做 ""+primitive 将其转换为字符串。

    【讨论】:

    • 从技术上讲,这不是转换而是转换。不过,它仍然很简单。
    • 你能详细说明一下java中基元转换和转换的区别吗?
    【解决方案4】:

    您尝试做的事情并没有真正意义......当您的函数使用原始参数(例如 int)调用时,它会自动装箱成整数。所以你还不如直接调用 obj.toString() 就可以了.....

    但是,如果您真的想对原语做一些特殊的事情,您可能需要使用方法重载来执行以下操作:

    private String toString(Object obj){
      return obj.toString();
    }
    
    private String toString(int intValue) {
      // code to return string for the primitive int case, assuming it is different
    }
    
    // more overloads for other primitive argument types as needed.....
    

    在某些情况下,这对于处理原语来说是一种非常有用的技术。

    【讨论】:

    • obj.toString() 不起作用(不能取消引用原始类型)。这就是我提出这个问题的全部原因。我必须知道它是什么包装器并以这种方式调用 toString() 方法,这就是我想要做的。
    【解决方案5】:

    代码中的直接问题是obj 是一个对象,因此不能是原始类型的实例。 (它必须是相应包装器类型的实例)。对于任何原始类型类,primClass.cast(obj) 调用都必须失败。

    但如果您只是想将原始包装器实例转换为字符串,只需调用实例的toString() 方法即可。

    【讨论】:

    • 问题在于 toString 方法接受原始类型作为参数——而不是包装器。我已经尝试将它转换为包装器类型并以这种方式传递它,但它会引发关于参数类型不匹配的异常。如您所料,尝试使用包装器类型作为参数的 toString 获取方法会引发 NoSuchMethodException。
    【解决方案6】:

    String.valueOf(arg) 也会做得很好。

    【讨论】:

    • 这样就简单多了。虽然我试图做的是一个有趣的实验(而且我无法弄清楚这一事实很烦人),但我认为这确实是答案。我不敢相信这从未出现在我尝试过的各种搜索中。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-07-17
    • 2015-02-15
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多