2013-04-16 11 views
7

私はこれを効果的に行い、一般的なメソッドを作成したいのですがそこにはNumber.valueOf()法ませんし、0をにキャストすることはできませんTJavaのジェネリックと数値型が

使用例:

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で可能な汎用的な方法の上に実装されていますか?はいの場合、どうですか?いいえ、良い代替アプローチは何ですか?


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

+1

['Number'](http://docs.oracle.com/javase/6/docs/api/java/lang/Number。html)抽象クラスには、文字列を型にパースするメソッドは含まれていません。これは、解析が特定の型によって行われるためです。提案はジェネリックを使用するのではなく、 '... ToInteger'、' ... ToDouble'などの関数を作成することです。 –

+0

私はそれを行う簡単な方法はないと思います。私は単に 'new MyClass(value).asDouble();'のようなものを使い、 'asInteger'、' asLong'、 'asFloat'、' asDouble'メソッドを手作業で実装します。 – assylias

+3

'T.valueOf()' wouldn '静的メソッド 'Number.valueOf()'があったとしても動作しません。このようなジェネリック型は使用できません。 –

答えて

3

私はTofuBeerに100%同意します。しかし、あなたは時間のために冗長性を避けたい場合には、これも実行する必要があります。Tから

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

} 

しかし、純粋に、実行時に型を取得することはできません。

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

使用法:

+0

これは私が質問で尋ねたものに最も近いアプローチのようですが、例外をキャッチして正しいサブクラスを返すように答えるのが好きです( 'T'を返し、' Class clas'パラメータを持っています。 )。 – hyde

+0

編集されました。ありがとう。 – Jatin

3

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

+0

@hyde:分かりません。 「いつもと同じ機能で、型の指定は何もしない」と言うと、型指定は何もしないと思うのはなぜですか?あなたの更新された例では、 'sloppyParseNumber'の戻り値の型は何でしょうか?渡された数値が 'BigDecimal'、' Double'、 'Float'、' Integer'などのように解析されるべきかどうかをどのように知るでしょうか? –

+0

もう一度やり直しましょう:MyClassの目的。 sloppyParseNumber'は、メソッドがDoubleオブジェクトを返すようにしていましたが、実際にはJavaジェネリックはそのようには動作しません。メソッドは呼び出し元が指定した型を '<>'で知ることができません。 – hyde

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

私は良いAPIは、 'NumberConvert.convert(Integer.class、string)'のような呼び出しを持ち、内部的に詳細を扱うことだと思います。 –

0

だから、私は別のアプローチを決定し、これが問題になっている方法よりも制限されていること

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

注、これは無効な変換されない、非数字列は"0"になります。これを完全に行うには、小数点をサポートするメソッドと整数をサポートするメソッドの2つのメソッドが必要です。

0

あなたはこれを試すことができます。

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

あなたはタイプがString型のパラメータを持つコンストラクタを持たなければならないことを考慮する必要があります。

関連する問題