【问题标题】:Java: How to determine if type is any of primitive/wrapper/String, or something elseJava:如何确定类型是原始/包装器/字符串中的任何一个,还是其他的
【发布时间】:2014-09-22 05:28:36
【问题描述】:

如果类型是原始类型、原始包装器或字符串,JDK 或通用基本库中是否有一个方法返回 true?

Class<?> type = ...
boolean isSimple = SomeUtil.isSimple( type );

对此类信息的需求可以是例如检查某些数据是否可以用 JSON 等格式表示。使用单一方法的原因是能够在表达式语言或模板中使用它。

【问题讨论】:

  • 基元不是对象,因此它们不是任何类的实例。这里一切都很简单。检查包装器:一个instanceof Number。检查字符串:str instanceof String.
  • @DmitryTsechoev:1)你误读了这个问题。还有用于原始类型的Class 对象(请参阅Double.TYPE)并且应该测试这些对象,而不是类/原始变量/字段的实例。 2) 对象是Number 的实例并不意味着它是原始包装器(例如BigInteger 不是原始包装器,但它是Number

标签: java types


【解决方案1】:

我发现了一些东西:

Commons Lang:(必须结合检查字符串)

ClassUtils.isPrimitiveOrWrapper()

Spring:

BeanUtils.isSimpleValueType()

这是我想要的,但希望在 Commons 中拥有它。

【讨论】:

    【解决方案2】:

    如果类型是原始类型,是否有一个方法返回 true

    Class.isPrimitive:

    Class<?> type = ...;
    if (type.isPrimitive()) { ... }
    

    请注意,void.class.isPrimitive() 也是如此,这可能是也可能不是您想要的。

    原始包装器?

    没有,但只有八个,所以你可以明确地检查它们:

    if (type == Double.class || type == Float.class || type == Long.class ||
        type == Integer.class || type == Short.class || type == Character.class ||
        type == Byte.class || type == Boolean.class) { ... }
    

    一个字符串?

    简单地说:

    if (type == String.class) { ... }
    

    这不是一种方法。我想用一种方法确定它是其中一个命名的还是其他的。

    好的。怎么样:

    public static boolean isPrimitiveOrPrimitiveWrapperOrString(Class<?> type) {
        return (type.isPrimitive() && type != void.class) ||
            type == Double.class || type == Float.class || type == Long.class ||
            type == Integer.class || type == Short.class || type == Character.class ||
            type == Byte.class || type == Boolean.class || type == String.class;
    }
    

    【讨论】:

    • 这不是一种方法。我想用一种方法确定它是那些命名的还是其他的。
    • 你说“只有八个”。 BigIntegerBigDecimal 和朋友呢?我可以很容易地认出它们也像原始人吗?
    • @StevePitchers Java 语言规范defines the eight primitive types explicitlyBigInteger 和朋友是引用类型(而且是相当复杂的类型!),尽管它们旨在通过不可变来像原语一样操作。实际上,这种不变性被打破了,因为他们忘记了创建这些类finalString"value-based" 类(如 Optional)是“类原始”引用类型的更好候选者。
    【解决方案3】:

    java.util.Class 类型有正确的方法:

    Class<?> type = ...
    
    boolean primitive = type.isPrimitive();
    boolean string_ = type == String.class;
    boolean array = type.isArray();
    boolean enum_ = type.isEnum();
    boolean interf_ = type.isInterface();
    

    【讨论】:

    • 1) 这不是单一方法,2) 如果它是 String 的子类(即在某些使用 Java 的脚本语言中)会怎样
    • 1) 我只是提供了提问者可能感兴趣的其他类似方法。 2)java.lang.Stringfinal类,所以type不能是String的子类。你不能扩展java.lang.String
    • 类是最终的现在没有任何意义。请参阅 Javassist。
    • 如果你想操作字节码或者内存,那么任何事情都没有好的解决方案,因为它可以在后台修改或者可以改变显示的值。
    【解决方案4】:

    Guava 为 Primitives 类提供了 Primitives.isWrapperType(class),它为 IntegerLong、...返回 true

    【讨论】:

      【解决方案5】:

      Integer、Float、Character 等不是基元;它们是包装类,用作原语的容器。它们是参考对象。真正的原语是 int、float、double、long、byte、char 和 boolean 等类型——非对象类型。有很大的不同,因为

      浮点值实例

      如果 "value" 是原语,甚至不会编译。 “字符串”也不是原始的——它是一种对象。 'null' 也不是原语——它是一个文字值。

      【讨论】:

      【解决方案6】:

      不,没有。而且不应该。对于树差异问题,您应该提供树不同的答案。

      public static <T> boolean  isPrimitive(Class<T> klass) {
      
          return klass.isPrimitive();
      }
      
      public static <T> boolean isString(Class<T> klass) {
      
          return String.class == klass; //String is final therefor you can not extend it.
      
      }
      
      public static <T> boolean isPrimitiveWrapper(Class<T> klass) {
      
          return Character.class == klass || Boolean.class == klass || klass.isAssignableFrom(Number.class);
      
      }
      

      【讨论】:

      • isPrimitiveWrapper(BigInteger.class) 将返回 true,您需要明确检查所有包装器类型。
      猜你喜欢
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2019-06-02
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多