質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Java

    15831questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

プリミティブ型をラッパークラスで定義するメリットはありますか

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 5,128

shoChan

score 37

現在携わっている案件のコードにて、以下のようなコードを見かけます。

Integer i = 20;
//なんかする
if(i.equals(100)){
...
}
コード


や、
以下はメソッドの定義ですが、

private Boolean isSomething() {
...
return false;
}
コード

のようなコードです。

コードの全体像は載せられず恐縮ですが、
なんらかメリットや意義があるようでしたらお教えください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

Javaのプリミティブ型はオブジェクト(ここではObjectを継承したなんらかのクラスのインスタンスであるということ)ではないため、次のような欠点があります。

  1. ジェネリックに使えない。(List<T>やOtinoal<T>等に使えない)
  2. synchronizedブロックに使えない。
  3. nullableでは無い。(未定義ならnullとか、エラーの場合にnullを返すと言うことができない)

1.についてはOptionalIntやIntStreamとか一部直接扱える物がありますが、intlongdoubleしかなく、そして、なぜかArrayListIntのような物は存在しません。2.はnull安全を提供するという意味でむしろ利点です。

これを踏まえてラッパークラスを変数の型や返り値として使う利点を言うと、

  1. ジェネリックを使用するList<Integer>とかに入れていくときオートボクシングが発生しないから、速い。(その代わり、普通の四則演算とか、代入ではオートボクシングしまくりで遅い)
  2. synchronizedブロックに使える。(やってはいけません)
  3. エラーの時はnullを返すといういけている(と本人は思っている)メソッドが作れる。(なぜ、例外を使わないかというと、例外は遅くなるからと言う最もらしいバカげた理由を付ける)
  4. スタックに積まれない!(参照値はスタックに積まれるんだけどな)
  5. プリミティブ型が無ければ真のオブジェクト指向だ!!(C++的オブジェクト指向なのに真とかw)

すいません。私にはまったくもって利点がわかりませんでした。あえて言えば最後の5.でしょうが、Integer#add(Integer other)のようなメソッドが存在しない時点で凄い片手落ちだと思います。


つまり、私の結論はただ一つ。早くJava捨ててScalaやろうぜって事です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/18 21:20

    ありがとうございます。欠点および利点が列挙されていて理解しやすかったためベストアンサーにします。
    Scalaにもちょっと手を出してみます。

    キャンセル

+3

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/18 00:07

    Boolean.valueOf(false)も結局Boolean.FALSEを返しますよ(ドキュメント参照)。
    判定のひと手間が入るくらいでしょうか。

    キャンセル

  • 2016/12/18 00:23 編集

    書き方が悪かったのでnewするものと考えているかのように読めちゃいますね。おっしゃるとおりstaticメソッド起動と判定が入るだけです。それで効率を気にするというのも細かすぎる話ではありましたね。

    キャンセル

+1

前半のコードに関しては全く利点を見出せません。Integerに対して何かすることと言ったらたいてい計算になるわけですが、Integerは不変オブジェクトのため、計算に際して
アンボクシング→計算→ボクシング
という、非常に手間のかかることを強要されます。
尤も、ListなどのCollection系はプリミティブを使えないため、例えばMapである文字列の個数を数えたいというような場合はそうせざるを得ませんが、そういう状況でもなさそうなので、あえてラッパークラスで操作する意味はほとんどありません。Integer独自のメソッドを使いたいならその時だけボクシングすれば済みますし、その大概はプリミティブに対する演算子で十分カバーできます。

後半のコードも、通常はこんなことするのはまずないと思われますが、

親クラスで返り値がObjectまたはジェネリクスで定義されたメソッドを子クラスでオーバーライドし、返り値をbooleanにしたいとき

は例外になります。返り値が参照型で定義されたメソッドをオーバーライドで返り値をプリミティブにすることはできないため、ラッパークラス型で再定義することになります。
ただこちらも、子クラスでbooleanで返すメソッドを親でObject型で定義するということ自体変ですし、そうなったら構造から考え直したほうがよさそうに思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

プリミティブのラッパクラスですが、型変換のメソッドはよく利用します。

たとえば、
valueOf()やto***()などは、
値となるインスタンスの変数名そのままに型変換するコードが記述できることは、
変数が主語となり、コードの文脈が追いやすくまたメソッド名が表す文字表記上の意味合いもわかりやすいです。

また、Javaのラッパークラスには、
ラップ対象となったプリミティブ型に適した処理をしてくれるメソッドが定義されていたりするので便利だと思います。

例)
Integer.signum() : 対象オブジェクトの符号(+/-)を数値で返却。

また下記ですが、
プリミティブになるreturn値をクラスメソッドでくるんでいる点についての観点で記載させていただきます。

private Boolean isSomething() {
...
return false;
}
コード

この形式のメリットは、
メソッド名によって論理的な意味合いを持せられることが最大の理由だと思います。

returnに至る前のコードで、メソッド名の意味に対応する処理を行うことで、

・メソッドの機能に対する透過性
・部品の再利用性
・コードの保守性
・複数人数による開発時の責務の分割と効率性

を向上させる効果があります。

もちろん、APIの持つ論理的な構成が適切であることが重要な前提となりますが、
ラップというワンクッションをはさむことは、
プログラムのコード間が疎結合となり開発プロジェクトでは大きなメリットをもたらします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/18 16:07 編集

    「メソッド名によって論理的な意味合いを持せられること」以降の主張がよくわからなかったのですが、列挙されている○○性は「boolean型ではなくBooleanクラスへと置き換えること」で得られる利点として主張されているのでしょうか?

    キャンセル

同じタグがついた質問を見る

  • Java

    15831questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。