开发者

Given a Class<?>, can I determine if it subclasses a particular type?

I'm trying to write a Java function that takes a Class<?> and returns a string which represents a reasonable guess at the corresponding JavaScript type. Example input/output:

   in              |  out
---------------------------------
 String.class      |  "string"
 int.class         |  "number"
 double.class      |  "number"
 Integer.class     |  "number"
 Date.class        |  "date"    (yes, I know that typeof new Date() === 'object')
 boolean.class     |  "boolean"
 Foo.class         |  "object"

Here's what I've got so far, and it seems to mostly work:

String jsType(Class<?> clazz)
{
    if (clazz.equals(String.class) return "string";

    if (clazz.equals(boolean.class) return "boolean";

    try
    {
        clazz.asSubclass(Number.class);
        return "number";
    }
    catch (Exception e){}

    try
    {
        clazz.asSubclass(Date.class);
        return "date";
    }
    catch (Exception e){}

    return "object";
}

However, it does not correctly return "number" for number primitives, e.g. int.class, double.class, etc., though it does work correct开发者_StackOverflow社区ly for the wrapper types, Integer.class et al.

  • Is there something special about the class literals for primitive types?
  • Is there a way to write this function that's better than a bunch of if-else statements, for every class I'm interested in?


There are two questions. For the first, the answer is that there is nothing special about the class literals for primitive types, other than the obvious: that they represent primitive types. The "isPrimitive()" method will return true for such types. You seem to be expecting that the primitive "class" types are subclasses of Number, but that is not the case, as your example shows.

Is there a better way to write the function than a bunch of if-else statements? probably not! Although I would try to avoid using exceptions as a test, exceptions should be reserved for truly exceptional conditions; use isAssignableFrom(Class<?>) instead - though I guess that's more a matter of style (and perhaps efficiency).


Here's an approach that normalises classes first, simplifying the jsType method:

Class<?> normalise(Class<?> cls) {
    if (Number.class.isAssignableFrom(cls) ||
        cls == int.class || cls == long.class || 
        cls == double.class || cls == float.class) {
        return Number.class;
    } else if (cls == Boolean.class || cls == boolean.class) {
        return Boolean.class;
    } else if (Date.class.isAssignableFrom(cls)) {
        return Date.class;
    } else {
        return cls;
    }
}

String jsType(Class<?> cls) {
    Class<?> normalised = normalise(cls);
    if (normalised == Number.class) {
        return "number";
    } else if (normalised == Boolean.class) {
        return "boolean";
    } else if (normalised == Date.class) {
        return "date";
    } else if (normalised == String.class) {
        return "string";
    } else {
        return "object";
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜