2008-08-07 6 views
46

私は文字列にプリミティブを変換したい、と私はみました:なぜ、Javaの自動ボクシングは、自動ボクシングタイプのメソッドのメソッド呼び出しにまで拡張されていないのですか?

myInt.toString(); 

これはエラーで失敗します。

int cannot be dereferenced 

、私は、すなわち(プリミティブ型を参照していないということではない取得オブジェクト)、メソッドを持つことはできません。しかし、Java 5ではオートボクシングとアンボクシングが導入されました(これはC#ではこれまで好きではなかったが、それはポイントの横にある)。オートボクシングでは、私は上記のmyIntをIntegerに変換して、その上でtoString()を呼び出すことを期待しています。

さらに、間違って覚えていない限り、C#はそのような呼び出しを許可すると信じています。これは、Javaのautoboxing/unboxing仕様の不幸な欠点か、これには正当な理由がありますか?

答えて

44

Javaオートボクシング/アンボクシングは、プリミティブを逆参照できない程度には進まないため、コンパイラはそれを防止します。あなたのコンパイラは依然としてプリミティブとしてmyIntを知っています。この問題に関する記事はjcp.orgです。

オートボクシングは、主にオブジェクトとしてプリミティブを渡すことができます(またはその逆)、またはプリミティブをオブジェクトに割り当てる(またはその逆)ことができます。

ので、残念ながら、あなたはこのようにそれをしなければならないでしょう:ジャスティンが言ったことに

Integer.toString(myInt); 
26

同上(名声パトリックは、私はあなたの方法に切り替え)、しかし、あなたの代わりにこれを行う必要があります。

Integer.toString(myInt); 

1つまたは2つの割り当てが保存され、読みやすくなります。

8

seems like a shortcoming of the specification to me

さらに多くの欠点があり、これは微妙なトピックです。外thisをチェック:コンパイラはオートボクシングの上に広げchosesがあるため、「長い」ここ

public class methodOverloading{ 
    public static void hello(Integer x){ 
     System.out.println("Integer"); 
    } 

    public static void hello(long x){ 
     System.out.println("long"); 
    } 

    public static void main(String[] args){ 
     int i = 5; 
     hello(i); 
    } 
} 

、(それを自分でチェックしていない)印刷されます。オートボクシングを使用する場合や、まったく使用しない場合は注意してください。それを行うには

14

もう一つの方法は、使用することです。

String.valueOf(myInt); 

この方法では、すべてのプリミティブ型とObjectのために過負荷になっています。この方法では、使用しているタイプについて考える必要はありません。このメソッドの実装では、指定されたタイプの適切なメソッドが呼び出されます。 Integer.toString(myInt)

http://java.sun.com/javase/6/docs/api/java/lang/String.htmlを参照してください。

0

C#では、整数は参照型でもなく、ToString()を呼び出すためにはボックス化する必要もありません。ただし、であり、フレームワーク内のオブジェクトと見なされます(ValueTypeとして値セマンティクスがあるため)。 CLRでは、プリミティブのメソッドは、スタック(ldind)にロードする間接的に呼び出されます。あなたの例に最も近い

4

有効な構文は、

((Integer) myInt).toString(); 

コンパイラが終了すると、それはしかし、これは、従来の使用法、String.valueOf(myInt)と同様に実行されません

Integer.valueOf(myInt).toString(); 

に相当しますです特別な場合を除いて、新しいIntegerインスタンスが作成された後すぐにそれを投げ捨てるので、不要なゴミが増えます。 (小さな範囲の整数がキャッシュされ、配列アクセスによってアクセスされます。)おそらく言語設計者は、パフォーマンス上の理由からこの使用法を妨げたかったでしょう。

編集:なぜこれが役に立たないのかについてdownvoter(s)がコメントすると感謝します。

+1

私はすべてのダウン投票者が何かが投票に落ちる理由についてコメントしたいと思います。私はそれが明らかでない限り(答えはまったく間違っている、ナンセンスなので)常に行います。 –

+0

おそらくコードビットを読んで、あなたがそのようなコードを主張していると思った人々によって投票された可能性があります。 – Kris

0

誰もが指摘しているように、オートボクシングではコードを単純化できますが、そのプリミティブは複雑なタイプのふりをすることはできません。

また興味深い:"autoboxing is a compiler-level hack"をJavaでご覧ください。 Autoboxingは基本的にJavaに追加された奇妙なkludgeです。それがどれほど奇妙であるかについては、this postを参照してください。

0

Javaのプリミティブ型を操作するために、特定の静的メソッドを定義し、コンパイラにいくつかのシンタックスシュガーを建てた場合

5.asInteger 

some.magic.stuff.Integer.asInteger(5); 

と同等になるようにそれは私がドン参考になりますそのような機能は現行のルールでコンパイルされたコードとの非互換性を引き起こすと考えています。多くの場合、構文の乱雑さを軽減するのに役立ちます。 Javaが参照解除されたプリミティブを自動抑制するのであれば、参照解除構文を静的メソッド呼び出し(実際には.NETで起こるもの)にマッピングしていると推測されることがあり、その形式で記述された操作は、同等の静的メソッド呼び出し。間接参照スタイルのメソッドが可能かもしれないが、人々に悪いコード(例えば、自動ボクシング逆参照されたプリミティブ)を書くことを促す新しい言語機能を追加することは良い考えのようには見えない。

関連する問題