有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

运行时的java编译时类型

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);

第一次呼叫-->;号码

第二次呼叫-->;反对

第三次呼叫-->;整数

编辑:这是问题的一个非常简化的版本。我试图做的是在框架内检测(而不是被告知)正在传递的对象的元数据。可能发生的情况是,首先使用整数调用该方法,然后使用双精度,两者都声明为数字


共 (5) 个答案

  1. # 1 楼答案

    可以使用“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
    
  2. # 2 楼答案

    很简单,你不能

    您已经知道函数参数(Object)的编译时,并且可以找到传入的对象的运行时类型(通过使用getClass())。然而,没有办法得到你想要的信息

  3. # 3 楼答案

    使用对象。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);
    
  4. # 4 楼答案

    你不能。Integer是正确的答案,因为Number是一个抽象类,你不能有一个抽象类的实例,你依赖自动装箱来转换原语int

  5. # 5 楼答案

    我看到的唯一方法就是使用重载。但您需要为继承关系的每个类指定一个覆盖方法,以排除子类

    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.