Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improvement/s to my Java generic console input method?

Using Java Generics, I tried to implement a generic console input method.

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

I'm having a warning "Type safety: Unchecked cast from Integer to T". Aside from @SuppressWarnings, is it possible to avoid this warning?

Are there better ways to implement my method? Thanks in advance

like image 983
thirdy Avatar asked Jul 19 '10 10:07

thirdy


2 Answers

You can use the Class#castmethod instead, but should leave some comments, because even though cast does not create a warning, it can throw a ClassCastException at runtime if the cast is not possible.

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

Note that I've changed the method signature slightly - it should be Class<T> and not Class<?> to guarantee, that the Class instance is consistent with the type parameter.

like image 173
Andreas Dolk Avatar answered Oct 22 '22 14:10

Andreas Dolk


Others have shown how you can do it with Class.cast, but how should you do it?

I suggest readInt, readString, readFloat and readDouble methods. Also, I suspect Scanner may buffer, which could lead you into trouble.

like image 28
Tom Hawtin - tackline Avatar answered Oct 22 '22 14:10

Tom Hawtin - tackline