改进我的Java通用控制台输入法?

时间:2010-07-19 10:49:54

标签: java generics input console

使用Java Generics,我尝试实现通用控制台输入法。

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,是否可以避免此警告?

有没有更好的方法来实现我的方法?提前致谢

8 个答案:

答案 0 :(得分:7)

您可以使用Class#cast方法,但应该留下一些注释,因为即使cast没有创建警告,如果无法进行强制转换,它也会在运行时抛出ClassCastException。 / p>

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<T>而不是Class<?>来保证Class实例与类型参数一致。

答案 1 :(得分:2)

其他人已经展示了如何使用Class.cast来完成它,但是你应该怎么做呢?

我建议使用readIntreadStringreadFloatreadDouble方法。此外,我怀疑Scanner可能会缓冲,这可能会让您陷入困境。

答案 2 :(得分:2)

我认为你可能会试图过度抽象问题。这样做有什么不对?

    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,“保持简单愚蠢”......

答案 3 :(得分:1)

这样做:

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

答案 4 :(得分:0)

阅读这篇文章, Java generic function: how to return 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;
    }

答案 5 :(得分:0)

除了使用@SuppressWarnings (unchecked)注释之外,没有一般方法可以避免“未经检查的强制转换”警告。

在特殊情况下,您会收到此警告,因为无法保证参数Class<?> c可以转换为T,因为仅在编译时检查Java的泛型,并且不会在运行时进行检查。

答案 6 :(得分:0)

您可以执行以下操作:

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

但是,我强烈建议不要抛出异常。抛出一个更具体的异常(原始运行时异常或一些适当的已检查异常)。

答案 7 :(得分:0)

您可以使用传入的具体类来抛弃警告:

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

在这种情况下,我会试图用你想要的类型覆盖多个readFromInput方法,例如:     public static Float readFromInput(String message,Class c)     public static Integer readFromInput(String message,Class c) 等