8

これを効果的に行うジェネリックメソッドを作成したいと思います:

class MyClass {

    static <T extends Number> T sloppyParseNumber(String str) {
        try {
            return T.valueOf(str);
        } catch (Exception e) {
            return (T)0;
        }
    }
}

上記は 2 つの理由でコンパイルされません。Number.valueOf()メソッドがないことと 0 を にキャストできないことTです。

使用例:

String value = "0.00000001";

System.out.println("Double: " + MyClass.<Double>sloppyParseNumber(value));
System.out.println("Float: " + MyClass.<Float>sloppyParseNumber(value));

double d = MyClass.sloppyParseNumber(value);
float f = MyClass.sloppyParseNumber(value);

Javaで上記のジェネリックメソッドを実装することは可能ですか? はいの場合、どのように?いいえの場合、良い代替アプローチは何ですか?


編集:重複の可能性がいくつかあるようですが、これを正確にカバーするものは見つかりませんでした。Number文字列をサブクラスに解析し、サブクラスに 0 の値を返すという 2 つの操作を可能にする、プルするトリックがあることを願っていNumberます。

4

5 に答える 5

3

Javaジェネリックはコンパイル時のチェックのみを提供し、型情報はコンパイル後にほとんど破棄されます. したがって、このステートメントT.valueOfは Java では使用できません。解決策は、コメントで既に述べたように冗長な方法をとることです。また、コンパイル時にタイプを指定しているので、MyClass.<Double>sloppyParseNumber(value)やりたい理由はありますか?MyClass.sloppyParseDouble(value)

于 2013-04-16T06:41:14.080 に答える
3

TofuBeerに100%同意します。ただし、時間を節約するために冗長性を避けたい場合は、次のことも行う必要があります。

static <T extends Number> T sloppyParseNumber(String str,Class<T> 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では、実行時に型を取得することはできません。

于 2013-04-16T06:55:41.433 に答える
2

静的メソッドは型によってバインドされます。これは、型がせいぜいあり、Number目的Numberのメソッドが機能しないためvalueOfです。

最も簡単な方法はsloppyParseIntsloppyParseFloat、 などのいくつかの静的メソッドを作成することです...

あなたはこのようなことをすることができますが、私はそれが好きかどうかわかりません.

public class Main 
{
    private static final Map<Class<? extends Number>, 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 extends Number>
{
    T convert(String str);
}

class IntegerConverter
    implements NumberConverter<Integer>
{
    @Override
    public Integer convert(String str) 
    {
        try
        {
            return Integer.valueOf(str);
        } 
        catch (NumberFormatException ex) 
        {
            return 0;
        }    
    }
}
于 2013-04-16T06:46:19.223 に答える
0

これを試すことができます:

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

ここで、Type には String パラメーターを持つコンストラクターが必要であることを考慮する必要があります。

于 2016-04-22T23:04:48.397 に答える