現在携わっている案件のコードにて、以下のようなコードを見かけます。
java
1Integer i = 20; 2//なんかする 3if(i.equals(100)){ 4... 5} 6コード
や、
以下はメソッドの定義ですが、
java
1private Boolean isSomething() { 2... 3return false; 4} 5コード
のようなコードです。
コードの全体像は載せられず恐縮ですが、
なんらかメリットや意義があるようでしたらお教えください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
Javaのプリミティブ型はオブジェクト(ここではObjectを継承したなんらかのクラスのインスタンスであるということ)ではないため、次のような欠点があります。
- ジェネリックに使えない。(List<T>やOtinoal<T>等に使えない)
- synchronizedブロックに使えない。
- nullableでは無い。(未定義なら
null
とか、エラーの場合にnull
を返すと言うことができない)
1.についてはOptionalIntやIntStreamとか一部直接扱える物がありますが、int
、long
、double
しかなく、そして、なぜかArrayListIntのような物は存在しません。2.はnull安全を提供するという意味でむしろ利点です。
これを踏まえてラッパークラスを変数の型や返り値として使う利点を言うと、
- ジェネリックを使用するList<Integer>とかに入れていくときオートボクシングが発生しないから、速い。(その代わり、普通の四則演算とか、代入ではオートボクシングしまくりで遅い)
- synchronizedブロックに使える。(やってはいけません)
- エラーの時は
null
を返すといういけている(と本人は思っている)メソッドが作れる。(なぜ、例外を使わないかというと、例外は遅くなるからと言う最もらしいバカげた理由を付ける) - スタックに積まれない!(参照値はスタックに積まれるんだけどな)
- プリミティブ型が無ければ真のオブジェクト指向だ!!(C++的オブジェクト指向なのに真とかw)
すいません。私にはまったくもって利点がわかりませんでした。あえて言えば最後の5.でしょうが、Integer#add(Integer other)のようなメソッドが存在しない時点で凄い片手落ちだと思います。
つまり、私の結論はただ一つ。早くJava捨ててScalaやろうぜって事です。
投稿2016/12/17 10:04
総合スコア21733
0
javaの言語仕様上の制約としてジェネリック型の要素としてプリミティブ型が使えないのでList,HashMap等々の要素にint,booleanを入れたい場合はInteger,Boolean等々を使わざるを得ません。そういう目的があるならやむをえずということになるでしょう。
前者のコードは、「なんかする」部分にiがIntegerでないと都合が悪い点があると考えられます。ただ比較はi==100としたほうがいいような気がします。見やすいですし、i.equals(100)と書くとboxingによりヒープが消費される可能性があります。i==100ならiがunboxingなのでヒープの消費はなく効率面からも少しよいコードと思います。
後者のfalseを返すコードはBoolean.FALSEと書いたほうが若干効率がよいかも知れません。なぜならfalseとかくとboxingのため暗黙的にBoolean.valufOf(false)が呼び出されるからです。しかし見やすさの点からいえばfalseと書きたいと自分は思います。高頻度で呼び出されるなら効率を気にするかもしれません。
最近別の質問の回答でも見かけましたが効率について気にするなら(中の仕組みを知っておくことに損はないものの)性能評価して実際の問題を見つけることのほうが大切なのだろうと思います。性能上問題ないことろでfalse/Boolean.FALSEのどちらがいいとかは時間のあるときに「やってみる」ならいいものの、これに拘泥しすぎないほうがよいかも知れませんね。
投稿2016/12/17 06:03
編集2016/12/17 07:37総合スコア18392
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/17 16:04 編集
0
前半のコードに関しては全く利点を見出せません。Integerに対して何かすることと言ったらたいてい計算になるわけですが、Integerは不変オブジェクトのため、計算に際して
アンボクシング→計算→ボクシング
という、非常に手間のかかることを強要されます。
尤も、ListなどのCollection系はプリミティブを使えないため、例えばMapである文字列の個数を数えたいというような場合はそうせざるを得ませんが、そういう状況でもなさそうなので、あえてラッパークラスで操作する意味はほとんどありません。Integer独自のメソッドを使いたいならその時だけボクシングすれば済みますし、その大概はプリミティブに対する演算子で十分カバーできます。
後半のコードも、通常はこんなことするのはまずないと思われますが、
親クラスで返り値がObjectまたはジェネリクスで定義されたメソッドを子クラスでオーバーライドし、返り値をbooleanにしたいとき
は例外になります。返り値が参照型で定義されたメソッドをオーバーライドで返り値をプリミティブにすることはできないため、ラッパークラス型で再定義することになります。
ただこちらも、子クラスでbooleanで返すメソッドを親でObject型で定義するということ自体変ですし、そうなったら構造から考え直したほうがよさそうに思います。
投稿2016/12/18 06:55
総合スコア20649
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
プリミティブのラッパクラスですが、型変換のメソッドはよく利用します。
たとえば、
valueOf()やto***()などは、
値となるインスタンスの変数名そのままに型変換するコードが記述できることは、
変数が主語となり、コードの文脈が追いやすくまたメソッド名が表す文字表記上の意味合いもわかりやすいです。
また、Javaのラッパークラスには、
ラップ対象となったプリミティブ型に適した処理をしてくれるメソッドが定義されていたりするので便利だと思います。
例)
Integer.signum() : 対象オブジェクトの符号(+/-)を数値で返却。
また下記ですが、
プリミティブになるreturn値をクラスメソッドでくるんでいる点についての観点で記載させていただきます。
Java
1private Boolean isSomething() { 2... 3return false; 4} 5コード
この形式のメリットは、
メソッド名によって論理的な意味合いを持せられることが最大の理由だと思います。
returnに至る前のコードで、メソッド名の意味に対応する処理を行うことで、
・メソッドの機能に対する透過性
・部品の再利用性
・コードの保守性
・複数人数による開発時の責務の分割と効率性
を向上させる効果があります。
もちろん、APIの持つ論理的な構成が適切であることが重要な前提となりますが、
ラップというワンクッションをはさむことは、
プログラムのコード間が疎結合となり開発プロジェクトでは大きなメリットをもたらします。
投稿2016/12/17 06:35
総合スコア41
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/12/18 12:20