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

发布于 2024-09-10 07:24:48 字数 849 浏览 4 评论 0原文

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

绝情姑娘 2024-09-17 07:24:48

您可以使用 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 code>instance 与参数类型一致。

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.

幽蝶幻影 2024-09-17 07:24:48

其他人已经展示了如何使用 Class.cast 来做到这一点,但是你应该怎么做呢?

我建议使用 readIntreadStringreadFloatreadDouble 方法。另外,我怀疑 Scanner 可能会缓冲,这可能会给您带来麻烦。

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.

瑾夏年华 2024-09-17 07:24:48

我认为你可能试图过度抽象这个问题。仅仅这样做有什么问题吗?

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

I think you might be trying to over abstract the problem. What's wrong with just doing this?

    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();

No cast required and you still have to handle the exception either way........

Remember KISS, "Keep It Simple Stupid"...

街角卖回忆 2024-09-17 07:24:48

这样做:

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

Do it like this:

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;
}
梦在夏天 2024-09-17 07:24:48

从这篇文章中读到,
Java泛型函数:如何返回泛型类型
我摆脱了我的警告:

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

Reading from this post,
Java generic function: how to return Generic type
I got rid of my warning:

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;
    }
拥抱没勇气 2024-09-17 07:24:48

除了使用 @SuppressWarnings (unchecked) 注释之外,没有其他通用方法可以避免“Unchecked cast”警告。

在特定情况下,您会收到此警告,因为不保证参数 Class c 可以强制转换为 T,因为 Java 的泛型仅在编译时进行检查,而在运行时不会进行检查。

There's no general way to avoid "Unchecked cast" warning other than using @SuppressWarnings (unchecked) annotation.

In particular case you get this warning because there's no warranty that parameter Class<?> c may be cast to T since Java's generics are checked only in compilation and no checks may be done in runtime.

乱世争霸 2024-09-17 07:24:48

您可以执行以下操作:

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

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

You can do the following:

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

However, I strongly recommend not throwing Exception. Throw a more specific exception (either the original runtime exception or some appropriate checked exception).

遇见了你 2024-09-17 07:24:48

您可以通过使用传入的具体类来转换对象来消除警告:

    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)
公共静态整数readFromInput(字符串消息,c类)
ETC。

You can get rid of the warning by using the concrete class you pass in to cast the object:

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

I would tempted in this case to implement multiple readFromInput methods overridden with your desired types, e.g.
public static Float readFromInput(String message, Class c)
public static Integer readFromInput(String message, Class c)
etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文