使用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,是否可以避免此警告?
有没有更好的方法来实现我的方法?提前致谢
答案 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
来完成它,但是你应该怎么做呢?
我建议使用readInt
,readString
,readFloat
和readDouble
方法。此外,我怀疑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) 等