2010-12-11 2 views
1

編集:これ以降解決されています。助けてくれた皆様に感謝します。正しいラッパークラスとしてオブジェクトをキャストした後にメソッドを呼び出す。しかし、String.valueOf()は、同じ効果を達成するためにずっと簡単です。Javaのプリミティブに動的にキャスト

こんにちは -

私がやろうとしていることさえできないかもしれません。私は数時間かけてさまざまなことを研究して実験しました。だから私は最終的に誰かがこれが可能かどうかを知ることができるかどうかを尋ねました。

リフレクションを使用して、未知の型のプリミティブのラッパーをプリミティブとして動的にキャストできますか?

私は基本的に任意のタイプのプリミティブを文字列に変換する汎用のtoString関数を作成しようとしています。このような一見単​​純なことは、難しいことです(そして、それぞれの型をテストしてWrapper.class型であるかどうかを確認し、具体的にキャストすることができますが、この時点では私はちょうど頑固さを追求しています)。

以下は、ClassCastExceptionをスローします。 primClassクラスが正しいと思われる(primClass.getName()を印刷するときに "int"を与える)。

private String toString(Number obj){ 
    String result = ""; 
    try{ 
     Class objClass = obj.getClass(); 
     Field field = objClass.getDeclaredField("TYPE"); 
     Class primClass = (Class)field.get(obj); 
     Method method = objClass.getMethod("toString", new Class[]{primClass}); 
     Object args = new Object[]{primClass.cast(obj)}; 
     result = (String)method.invoke(null, args); 
    }catch(Exception ex){ 
     //Unknown exception. Send to handler. 
     handleException(ex); 
    } 
    return result; 
} 

私は少し失恋しています。誰にでもアイデアはありますか?どんな助けでも大歓迎です。

+1

'Double、Long、...'の 'toString'メソッドは何もしませんか? – khachik

答えて

0

Apache Commons Lang、特にToStringBuilder.reflectionToString()をご覧ください。たとえtoString()だけの依存関係を導入したくないとしても、それはオープンソースなので、実装を見ることができます。

method.invokeは、primivtesタイプの代わりにWrapperタイプを受け入れます。

+0

ああたわごと。私はそれを信じることができません。私はそれを試してみたが、うまくいかなかったと思ったが、私はラッパークラスを使ってメソッドを見つけようとしているに違いない。私は確かめることにした、そしてそれは働いた。私は今、かなり愚かな気分です。ありがとう。 – Apropos

0

コードでの直接の問題は、objがObjectであるため、プリミティブ型のインスタンスにすることができないことです。 (対応するラッパー・タイプのインスタンスでなければなりません)。 primClass.cast(obj)呼び出しは、任意のプリミティブ型クラスで失敗する必要があります。

しかし、単純にプリミティブラッパーインスタンスを文字列に変換する場合は、インスタンスのtoString()メソッドを呼び出すだけです。

+0

この問題は、toStringメソッドがラッパーではなく引数としてプリミティブ型を受け入れることです。私はラッパーの型としてそれをキャストしようとしたが、それを渡すが、引数型の不一致に関する例外をスローします。引数としてラッパー型を指定したtoStringをgetMethodに渡そうとすると、NoSuchMethodExceptionがスローされます。 – Apropos

0

私はあなたの質問には理解できないものがあるかもしれませんが、プリミティブの場合は""+primitiveを使って文字列にキャストすることができます。

+0

技術的には、これはキャスティングではなく変換です。しかし、まだ簡単です。 –

+0

javaのプリミティブのキャストと変換の違いについて詳しく説明できますか? – Istao

0

しようとしていることは実際には意味がありません。あなたの関数がプリミティブな引数(intなど)で呼び出されると、自動的に整数に変換されます。だから、あなたにもちょうどあなたが本当にプリミティブと特別な何かをしたい場合は、メソッドのオーバーロードを使用して、次のような何かをしたいかもしれませんが.....それに

をobj.toString()を呼ぶかもしれない:

private String toString(Object obj){ 
    return obj.toString(); 
} 

private String toString(int intValue) { 
    // code to return string for the primitive int case, assuming it is different 
} 

// more overloads for other primitive argument types as needed..... 

これは、場合によってはプリミティブを処理するための非常に便利なテクニックです。

+0

obj.toString()は機能しません(プリミティブ型は参照解除できません)。それが私がこの問題を思いついた理由の全部です。私はそれがどんなラッパーであるか知っていて、toString()メソッドをそのように呼び出す必要がありました。これは私がしようとしていたものです。 – Apropos

0

String.valueOf(arg)でもうまくいきます。

+0

それははるかに簡単です。私がしようとしていたことは興味深い実験でした(そして、私がそれを理解できなかったということは迷惑でした)。これは本当に答えです。私はこれが私が試みた様々な検索では決して現れなかったとは思いません。ありがとう。 – Apropos

3

おそらく私は何かが逃していますが、obj.toString()がそうです。

実装を見ると、Double.toString(..)またはLong.toString(..)などが呼び出され、実装はString.valueOf(value)となります。したがって、toString()を呼び出すと、自動的に必要なメソッドが呼び出されます。あなたの部分からの反射なし。

関連する問題