тип времени компиляции во время выполнения - PullRequest
2 голосов
/ 21 декабря 2011

Есть ли способ в 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);

1-й вызов -> Число

2-й вызов -> Объект

3-й вызов -> Целое число

Редактировать: Это очень упрощенная версия проблемы.То, что я пытаюсь сделать, это обнаружить (вместо того, чтобы сказать) внутри метаданных структуры о передаваемых объектах.Может случиться так, что метод сначала вызывается с целым числом, а затем с двойным, оба объявлены как число.

Ответы [ 5 ]

2 голосов
/ 21 декабря 2011

Единственный способ, которым я вижу, - использовать перегрузку. Но для исключения подклассов вам потребуется указать перекрывающий метод для каждого класса отношения наследования.

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 голос
/ 21 декабря 2011

Проще, вы не можете.

Вы уже знаете время компиляции аргумента функции (Object) и можете узнать тип времени выполнения переданного объекта (используя getClass()). Тем не менее, нет способа получить информацию, которую вы запрашиваете.

0 голосов
/ 21 декабря 2011

Вы не можете.Integer - правильный ответ, потому что Number - абстрактный класс, и у вас не может быть экземпляра абстрактного класса, и вы полагались на автобокс для преобразования примитива int.

0 голосов
/ 21 декабря 2011

вы можете использовать '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
0 голосов
/ 21 декабря 2011

Использовать 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);
...