Java中是否有任何方法可以在运行时获取引用的编译时类型?
示例:
private void doSomething(final Object o)
{
// do somthing
}
final Number n = 1;
doSomething(n);
final Object o = 1;
doSomething(o);
final Integer i = 1;
doSomething(i);
第一次通话 - >数字
第二次通话 - >对象
第3次通话 - >整数
编辑:这是问题的一个非常简化的版本。我想要做的是在关于被传递的对象的框架元数据中检测(而不是被告知)。可能发生的是,首先使用Integer调用该方法,然后使用Double调用该方法,两者都声明为Number。
答案 0 :(得分:2)
我看到的唯一方法是使用重载。但是你需要为继承关系的每个类指定一个重叠方法来排除子类。
private void doSomething(final Object o)
{
// do something
}
private void doSomething(final Number n)
{
// do something
}
private void doSomething(final Integer i)
{
// do something
}
final Number n = 1;
doSomething(n); // doSomething(final Number) is called.
答案 1 :(得分:1)
很简单,你做不到。
您已经知道函数参数(Object
)的编译时间,并且您可以找到传入的对象的运行时类型(使用getClass()
)。但是,没有办法获得您要求的信息。
答案 2 :(得分:0)
使用object.getClass()
private static void doSomething(final Object o) {
System.out.println(o.getClass().getSuperclass());
}
private static <T extends Number> void doSomething(final T o) {
System.out.println(o.getClass());
}
final Integer n = 2;
doSomething(n);
final Double n = 2D;
doSomething(n);
答案 3 :(得分:0)
你可以使用'instanceof'
public class Test {
private static void doSomething(final Object o){
if(o instanceof Number){
System.out.println("it's a number!");
}
System.out.println("canonical class : "+o.getClass().getCanonicalName());
}
public static void main(String[] args) {
Number n = new Integer(10);
doSomething(n);
}
}
打印出来
it's a number!
canonical class : java.lang.Integer
另一种选择是递归检查超类
public class Test {
private static Class<?> doSomething(final Object o){
// assuming o is not null
Class<?> klass = getSuperClass(o.getClass());
return klass;
}
private static Class<?> getSuperClass(Class<?> klass){
// if super class is object or null break recursion
if(klass.getSuperclass() == null || klass.getSuperclass().equals(Object.class)){
return klass;
}
// keep looking higher up
return getSuperClass(klass.getSuperclass());
}
public static void main(String[] args) {
Number n = new Integer(10);
System.out.println("n is a "+doSomething(n).getCanonicalName());
Object o = new Integer(10);
System.out.println("o is a "+doSomething(o).getCanonicalName());
Number d = new Double(10.0d);
System.out.println("d is a "+doSomething(d).getCanonicalName());
String s = "10";
System.out.println("s is a "+doSomething(s).getCanonicalName());
Object so = "10";
System.out.println("so is a "+doSomething(so).getCanonicalName());
}
}
打印出来
n is a java.lang.Number
o is a java.lang.Number
d is a java.lang.Number
s is a java.lang.String
so is a java.lang.String
答案 4 :(得分:0)
你做不到。 Integer
是正确答案,因为Number
是一个抽象类,你不能拥有抽象类的实例,并且依靠自动装箱来转换原语int
。