Динамическое приведение к примитивам в Java - PullRequest
1 голос
/ 11 декабря 2010

Редактировать: с тех пор это было решено. Спасибо всем, кто помог. Вызов метода после приведения объекта как правильный класс обертки сработал. Но String.valueOf () намного, намного проще достичь того же эффекта.

Hello -

То, что я пытаюсь сделать, может даже оказаться невозможным. Я провел несколько часов, исследуя и экспериментируя с различными вещами, поэтому я решил наконец спросить, не знает ли кто-нибудь, возможно ли это.

Можно ли с помощью отражения динамически приводить оболочку для примитива неизвестного типа в качестве примитива?

Я в основном пытаюсь создать универсальную функцию toString, которая может обрабатывать преобразование любого типа примитива в строку. Такая, казалось бы, простая вещь разочаровывающе трудна (и я знаю, что могу просто протестировать каждый тип, чтобы увидеть, относится ли он к типу Wrapper.class, и специально разыграть его, но на данный момент я просто преследую это из упрямства) 1009 *

Следующее создает исключение ClassCastException. Класс primClass представляется правильным (дает «int» при печати primClass.getName ()).

    private String toString(Number obj){
    String result = "";
    try{
        Class objClass = obj.getClass();
        Field field = objClass.getDeclaredField("TYPE");
        Class primClass = (Class)field.get(obj);
        Method method = objClass.getMethod("toString", new Class[]{primClass});
        Object args = new Object[]{primClass.cast(obj)};
        result = (String)method.invoke(null, args);
    }catch(Exception ex){
        //Unknown exception. Send to handler.
        handleException(ex);
    }
    return result;
}

Так что я немного растерялся, правда. У кого-нибудь есть идеи? Любая помощь будет принята с благодарностью.

Ответы [ 6 ]

3 голосов
/ 11 декабря 2010

Возможно, я что-то упускаю, но obj.toString() подойдет.

Если вы посмотрите на реализации, он вызывает String.valueOf(value), что, в свою очередь, вызывает Double.toString(..) или Long.toString(..) или что-то еще. Таким образом, вызов toString() автоматически вызывает требуемый метод. Без каких-либо размышлений с вашей стороны.

0 голосов
/ 11 декабря 2010

String.valueOf(arg) тоже сделает это хорошо.

0 голосов
/ 11 декабря 2010

То, что вы пытаетесь сделать, на самом деле не имеет смысла .... когда ваша функция вызывается с примитивным аргументом (например, int), тогда она автоматически помещается в целое число.Так что вы могли бы просто вызвать obj.toString () для него .....

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

private String toString(Object obj){
  return obj.toString();
}

private String toString(int intValue) {
  // code to return string for the primitive int case, assuming it is different
}

// more overloads for other primitive argument types as needed.....

Это может быть очень полезным приемом для работы с примитивами в некоторых случаях.

0 голосов
/ 11 декабря 2010

Возможно, в вашем вопросе есть что-то, чего я не понимаю, но для примитива вы можете сделать ""+primitive, чтобы привести его к строке.

0 голосов
/ 11 декабря 2010

Возможно, вы захотите взглянуть на Apache Commons Lang , особенно ToStringBuilder.reflectionToString () . Даже если вы не хотите вводить зависимость только для toString (), это открытый исходный код, поэтому вы можете взглянуть на реализацию.

method.invoke принимает типы Wrapper вместо типов primivtes.

0 голосов
/ 11 декабря 2010

Непосредственная проблема в вашем коде состоит в том, что obj является объектом, и поэтому не может быть экземпляром примитивного типа.(Это должен быть экземпляр соответствующего типа оболочки).Вызов primClass.cast(obj) должен завершиться неудачно для любого класса примитивного типа.

Но если вы просто хотите превратить экземпляр примитивной оболочки в строку, просто вызовите метод toString() экземпляра.

...