在运行时编译时间类型

时间:2011-12-21 17:01:56

标签: java runtime compile-time

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。

5 个答案:

答案 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