Javagenerics和数字类型

我想创建一个有效的通用方法:

class MyClass { static  T sloppyParseNumber(String str) { try { return T.valueOf(str); } catch (Exception e) { return (T)0; } } } 

现在上面没有编译有两个原因:没有Number.valueOf()方法,0不能转换为T

用法示例:

 String value = "0.00000001"; System.out.println("Double: " + MyClass.sloppyParseNumber(value)); System.out.println("Float: " + MyClass.sloppyParseNumber(value)); double d = MyClass.sloppyParseNumber(value); float f = MyClass.sloppyParseNumber(value); 

用Java实现上面的通用方法吗? 如果有,怎么样? 如果不是,有什么好的替代方法?


编辑:似乎有一些可能的重复,但我没有找到一个,它涵盖了这一点。 我希望有一些技巧可以提取,这将允许这两个操作:将字符串解析为Number子类,并为Number子类返回0值。

我同意100%与TofuBeer。 但是如果您希望为了时间而避免冗长,这也应该:

 static  T sloppyParseNumber(String str,Class clas) { if (clas == null) throw new NullPointerException("clas is null"); try { if(clas.equals(Integer.class)) { return (T) Integer.valueOf(str); } else if(clas.equals(Double.class)) { return (T) Double.valueOf(str); } //so on catch(NumberFormatException|NullPointerException ex) { // force call with valid arguments return sloppyParseNumber("0", clas); } throw new IllegalArgumentException("Invalid clas " + clas); } 

但纯粹来自T ,你无法在运行时获得类型。

Javagenerics只提供编译时检查,编译后几乎丢弃了类型信息。 所以语句T.valueOf在Java中是不可能的。 解决方案是采用评论中已经提到的冗长方式。 另外,你有什么理由要做MyClass.sloppyParseNumber(value)但不是MyClass.sloppyParseDouble(value)因为你无论如何在编译时指定类型?

静态方法受类型的约束,因为类型最多只有NumberNumber没有valueOf方法,所以你不能使用它。

最简单的方法是制作一些静态方法,如sloppyParseIntsloppyParseFloat等…

你可以做这样的事情,不确定我喜欢它,并且可以改进:

 public class Main { private static final Map, NumberConverter> CONVERTERS; static { CONVERTERS = new HashMap<>(); CONVERTERS.put(Integer.class, new IntegerConverter()); } public static void main(String[] args) { Number valueA; Number valueB; valueA = CONVERTERS.get(Integer.class).convert("42"); valueB = CONVERTERS.get(Integer.class).convert("Hello, World!"); System.out.println(valueA); System.out.println(valueB); } } interface NumberConverter { T convert(String str); } class IntegerConverter implements NumberConverter { @Override public Integer convert(String str) { try { return Integer.valueOf(str); } catch (NumberFormatException ex) { return 0; } } } 

所以,我决定采用另一种方法:

 static String trimTo0(String str) { if (str == null) return "0"; str = str.trim(); if (str.isEmpty()) return "0"; return str; } 

用法:

 String value = null; System.out println("Double value: " + Double.parseDouble(trimTo0(value))); 

请注意,这比问题中的方法更受限制,这不会将无效的非数字字符串转换为"0" 。 完全这样做需要两个单独的方法,一个支持小数点,另一个支持整数。

你可以试试这个:

 private  T convertToType(Class clazz,String str) throws Exception { return clazz.getConstructor(String.class).newInstance(str); } 

在这里,您需要考虑Type必须具有带String参数的构造函数。