Java 给定一个类<>;,我可以确定它是否属于特定类型的子类吗?

Java 给定一个类<>;,我可以确定它是否属于特定类型的子类吗?,java,Java,我试图编写一个Java函数,它接受一个类,并返回一个字符串,该字符串表示对相应JavaScript类型的合理猜测。输入/输出示例: in | out --------------------------------- String.class | "string" int.class | "number" double.class | "number" Integer.class | "number"

我试图编写一个Java函数,它接受一个
,并返回一个字符串,该字符串表示对相应JavaScript类型的合理猜测。输入/输出示例:

   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"
以下是迄今为止我所得到的,而且似乎大部分都有效:

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";
}
stringjstype(类clazz)
{
if(clazz.equals)(String.class)返回“String”;
if(clazz.equals)(boolean.class)返回“boolean”;
尝试
{
班级分组(编号、班级);
返回“数字”;
}
捕获(例外e){}
尝试
{
班级分组(日期分组);
返回“日期”;
}
捕获(例外e){}
返回“对象”;
}
但是,对于数字原语,例如,
int.class
double.class
等,它不能正确返回“number”,尽管它对包装类型,
Integer.class
等确实有效

  • 基元类型的类文本有什么特殊之处吗
  • 对于我感兴趣的每一个类,有没有一种编写这个函数的方法比一堆
    if-else
    语句更好

有两个问题。对于第一个问题,答案是基元类型的类文本没有什么特别之处,除了显而易见的:它们代表基元类型。“isPrimitive()”方法将为此类类型返回true。您似乎期望基元“class”类型是
Number
的子类,但事实并非如此,如您的示例所示


有没有比一堆if-else语句更好的方法来编写函数?可能没有!虽然我会尽量避免使用异常作为测试,但异常应该保留在真正的异常情况下;使用
isAssignableFrom(Class)
——尽管我想这更多的是风格问题(也许还有效率问题).

这里有一种方法,首先规范化类,简化
jsType
方法:

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";
    }
}
类标准化(类cls){
if(Number.class.isAssignableFrom(cls)||
cls==int.class | | cls==long.class | |
cls==double.class | | cls==float.class){
返回编号.class;
}else if(cls==Boolean.class | | cls==Boolean.class){
返回Boolean.class;
}else if(Date.class.isAssignableFrom(cls)){
返回日期.class;
}否则{
返回cls;
}
}
字符串类型(类cls){
标准化等级=标准化(cls);
如果(标准化==Number.class){
返回“数字”;
}else if(归一化==布尔.class){
返回“布尔”;
}else if(标准化==日期类){
返回“日期”;
}else if(归一化==String.class){
返回“字符串”;
}否则{
返回“对象”;
}
}

+1,
isAssignableFrom()
无疑是一种改进。我仍然很好奇为什么
Number.class.isAssignableFrom(int.class)
返回
false
-这一定是因为
int
是基元类型。@Matt int作为基元类型,不属于对象类型层次结构的一部分。因此,它不能高于或低于任何值(如数字)@ILMTitan:说得好。那么,你对处理这些问题的非特定方式有什么建议吗?例如,除了一堆
if-else
statements@Matt,只需检查
isPrimitive()即可合并对基元数字类型的检查
,在首先确保类型不是
布尔值之后
。对于非基本类型,如果您真的愿意,您可以使用hashmap从java类名映射到javascript类型。我认为您不能完全避免if-then-else。这似乎很好。您确定我可以使用
=
而不是
。equal吗当然,您也可以将这两种方法结合起来。这可能是最简单的。是的,您可以认为使用类==对于类的实例是安全的。它是规范的一部分,每个类加载器只有一个给定的类对象的一个实例。(它不重写默认均衡器)。总之,这就是你要开始的。)@Affe:谢谢你的澄清。我不习惯使用类文字(即
?)的实例。是的,Date.class==new Date()。getClass()是一个正确的语句,简单地说:)