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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

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

Q&A

解決済

4回答

13453閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

0グッド

0クリップ

投稿2016/12/17 05:34

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

java

1Integer i = 20; 2//なんかする 3if(i.equals(100)){ 4... 5} 6コード

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

java

1private Boolean isSomething() { 2... 3return false; 4} 5コード

のようなコードです。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

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/17 10:04

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/18 12:20

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

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
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/12/17 15:07

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

2016/12/17 16:04 編集

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

0

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

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

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

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

投稿2016/12/18 06:55

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

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

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

Java

1private Boolean isSomething() { 2... 3return false; 4} 5コード

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

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

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

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

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

投稿2016/12/17 06:35

KazumasaTanaka

総合スコア41

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2016/12/18 07:07 編集

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問