gpt4 book ai didi

java - 基于泛型类型的选择方法

转载 作者:搜寻专家 更新时间:2023-11-01 08:43:52 25 4
gpt4 key购买 nike

我正在尝试做这样的事情:

class MyClass<T extends Number> {
T value;
NumberFormat formatter = NumberFormat.getInstance();
public void setValueFromString(String s) {
try {
value = formatter.parse(s).doubleValue();
} catch (ParseException e) { }
}
}

当然,除了 doubleValue() 并不总是正确的方法——例如,如果 TInteger ,我想使用 intValue()。到目前为止,我发现处理此问题的唯一方法是将 setValueFromString() 方法抽象化,并且仅在指定 T 时在子类中定义它。

有没有一种方法可以在通用类中定义 setValueFromString() 方法来测试 T 并从 Number 中选择合适的转换方法>?我已经尝试过 instanceofClass.isInstance()Class.isAssignableFrom(),但这些都不起作用,出现编译时错误关于不允许以这种方式使用 T

最佳答案

无论哪种类型,您都必须有一个具体类:

尝试在运行时从泛型中推断出类似的东西并根据该信息对逻辑进行分支只会带来痛苦,并且会使您的代码极难理解且更容易被破坏。

您尝试做的更像是对类型系统的滥用,而不是利用它。一旦您使用 instanceof.getClass() 或任何 TypeToken magic 测试类型您可能做错了,尤其是对于无需所有这些废话就可以完成的事情。

只有这么多的 Number 子类,只需对它们进行硬编码并将它们链接到 Converter 的第一个非空返回值是适当类型的地方。

Guava 有一个叫做 Converter 的东西只是为了这样的事情。

例如:

final static ShortConverter sc = new ShortConverter();
final static IntegerConverter ic = new IntegerConverter();
final static DoubleConverter dc = new DoubleConverter();

public static void main(String[] args) throws ParseException
{
System.out.println("getNumber(\"1\").getClass().toString() = " + getNumber("1").getClass().toString());
System.out.println("getNumber(\"64000\").getClass().toString() = " + getNumber("64000").getClass().toString());
System.out.println("getNumber(\"3.14\").getClass().toString() = " + getNumber("3.14").getClass().toString());
}

public static Number getNumber(@Nonnull final String s)
{
/* nest the firstNonNull() as deeply as you need for the limited
number of types */
return firstNonNull(sc.doForward(s), firstNonNull(ic.doForward(s), dc.doForward(s)));
}

public static class DoubleConverter extends Converter<String, Double>
{
@Override
protected String doBackward(@Nonnull final Double d) { return d.toString(); }

@Override
protected Double doForward(@Nonnull final String s) { return Doubles.tryParse(s); }
}

public static class IntegerConverter extends Converter<String, Integer>
{
@Override
protected String doBackward(@Nonnull final Integer i) { return i.toString(); }

@Override
protected Integer doForward(@Nonnull final String s) { return Ints.tryParse(s); }
}

public static class ShortConverter extends Converter<String, Short>
{
@Override
protected String doBackward(@Nonnull final Short s) { return s.toString(); }

@Override
protected Short doForward(@Nonnull final String s) { try { return Short.parseShort(s); } catch (NumberFormatException e) { return null; } }
}

输出:

getNumber("1").getClass().toString() = class java.lang.Short
getNumber("64000").getClass().toString() = class java.lang.Integer
getNumber("3.14").getClass().toString() = class java.lang.Double

如果如何将其应用于问题不明显:

public class MyClass<T extends Number> 
{
T value;
final Converter<String,T> converter;

public MyClass(final Converter<String,T> c)
{
this.converter = c;
}

public void setValueFromString(String s)
{
this.value = this.converter.doForward(s);
}
}

关于java - 基于泛型类型的选择方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30267774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com