Improvement/s к моему Java универсальный консольный метод ввода?

Используя Дженерики Java, я пытался реализовать универсальный консольный метод ввода.

public static <T> T readFromInput(String message, Class<?> c) throws Exception{
        System.out.println(message);
        Scanner scanner = new Scanner(System.in);
        try {
            if(c == Integer.class)
                return (T) Integer.valueOf(scanner.nextInt());
            if(c == String.class)
                return (T) scanner.nextLine();
            if(c == Double.class)
                return (T) Double.valueOf(scanner.nextDouble());
            if(c == Float.class)
                return (T) Float.valueOf(scanner.nextFloat());
        } catch (InputMismatchException e) {
            throw new Exception(e);
        }
        return null;
    }

У меня есть предупреждение "Безопасность с точки зрения типов: Неконтролируемый бросок от Целого числа до T". Кроме @SuppressWarnings, действительно ли возможно избежать этого предупреждения?

Там лучшие пути состоят в том, чтобы реализовать мой метод?Заранее спасибо

5
задан thirdy 19 July 2010 в 10:49
поделиться

8 ответов

Вы можете использовать метод Class#castвместо этого, но должны оставить некоторые комментарии, потому что хотя cast не создает предупреждения, он может выбросить ClassCastException во время выполнения, если приведение невозможно.

public static <T> T readFromInput(String message, Class<T> c) throws Exception{
    System.out.println(message);
    Scanner scanner = new Scanner(System.in);
    try {
        if(c == Integer.class)
            // the next cast to Integer is safe
            return c.cast(Integer.valueOf(scanner.nextInt()));
        if(c == String.class)
            // the next cast to String is safe
            return c.cast(scanner.nextLine());
        if(c == Double.class)
            // the next cast to Double is safe
            return c.cast(Double.valueOf(scanner.nextDouble()));
        if(c == Float.class)
            // the next cast to Float is safe
            return c.cast(Float.valueOf(scanner.nextFloat()));
    } catch (InputMismatchException e) {
        throw new Exception(e);
    }
    return null;
}

Обратите внимание, что я немного изменил сигнатуру метода - она должна быть Class, а не Class, чтобы гарантировать, что экземпляр Class соответствует параметру типа.

7
ответ дан 18 December 2019 в 16:34
поделиться

Другие показали, как это можно сделать с помощью Class.cast , но как это сделать?

Я предлагаю readInt , readString , readFloat и readDouble методы. Кроме того, я подозреваю, что Сканер может буферизоваться, что может привести к неприятностям.

2
ответ дан 18 December 2019 в 16:34
поделиться

Я думаю, вы пытаетесь излишне абстрагироваться от проблемы. Что плохого в том, чтобы просто сделать это?

    Scanner scanner = new Scanner(System.in);

    System.out.println("Give me a boolean:");
    boolean bool = scanner.nextBoolean();

    System.out.println("Give me an integer:");
    int integer = scanner.nextInt();

Приведение не требуется, и вам все равно придется обрабатывать исключение в любом случае ........

Помните KISS, "Keep It Simple Stupid" ...

2
ответ дан 18 December 2019 в 16:34
поделиться

Сделайте это так:

public static <T> T readFromInput(String message, Class<T> c) throws Exception{
    System.out.println(message);
    Scanner scanner = new Scanner(System.in);
    try {
        if(c == Integer.class)
            return c.cast(scanner.nextInt());
        if(c == String.class)
            return c.cast(scanner.nextLine());
        if(c == Double.class)
            return c.cast(scanner.nextDouble());
        if(c == Float.class)
            return c.cast(scanner.nextFloat());
    } catch (InputMismatchException e) {
        throw new Exception(e);
    }
    return null;
}
1
ответ дан 18 December 2019 в 16:34
поделиться

Чтение из этого поста, Java generic function: как вернуть Generic type , я избавился от предупреждения:

public static <T> T readFromInput(String message, Class<T> c) throws Exception{
        System.out.println(message);
        Scanner scanner = new Scanner(System.in);
        try {
            if(c == Integer.class)
                return c.cast(scanner.nextInt());
            if(c == String.class)
                return c.cast(scanner.nextLine());
            if(c == Double.class)
                return c.cast(scanner.nextDouble());
            if(c == Float.class)
                return c.cast(scanner.nextFloat());
        } catch (InputMismatchException e) {
            throw new Exception(e);
        }
        return null;
    }
0
ответ дан 18 December 2019 в 16:34
поделиться

Не существует общего способа избежать предупреждения "Unchecked cast", кроме использования аннотации @SuppressWarnings (unchecked).

В конкретном случае вы получаете это предупреждение, потому что нет гарантии, что параметр Class c может быть приведен к T, поскольку дженерики Java проверяются только при компиляции, и никаких проверок не может быть сделано во время выполнения.

0
ответ дан 18 December 2019 в 16:34
поделиться

Вы можете сделать следующее:

    public static <T> T readFromInput(String message, Class<T> c) throws Exception{ 
       System.out.println(message); 
       Scanner scanner = new Scanner(System.in); 
       try { 
           if(c == Integer.class) 
               return c.cast(scanner.nextInt()); 
           if(c == String.class) 
               return c.cast(scanner.nextLine()); 
           if(c == Double.class) 
               return c.cast(scanner.nextDouble()); 
           if(c == Float.class) 
               return c.cast(scanner.nextFloat()); 
       } catch (InputMismatchException e) { 
           throw new Exception(e); 
       } 
       return null; 
   } 

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

0
ответ дан 18 December 2019 в 16:34
поделиться

Вы можете избавиться от предупреждения, используя конкретный класс, который вы передаете для приведения объекта:

    public static <T> T readFromInput(String message, Class<T> c) throws Exception{
        ..
            return c.cast(Integer.valueOf(scanner.nextInt()));
        ..
    }

В этом случае я бы хотел реализовать несколько методов readFromInput, переопределенных вашими желаемыми типами, например общедоступный статический Float readFromInput (строковое сообщение, класс c) общедоступное статическое целое число readFromInput (строковое сообщение, класс c) и т. д.

0
ответ дан 18 December 2019 в 16:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: