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

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

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

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

Q&A

解決済

3回答

3120閲覧

[==]と[equals]の挙動の違いを確認したい。

sakuman0

総合スコア15

Java

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

0グッド

1クリップ

投稿2016/10/12 08:52

編集2016/10/12 15:29

###前提・実現したいこと
[==]と[equals]の挙動の違いを確認したい。

###発生している問題・エラーメッセージ
意図した動作にならない。

###該当のソースコード
public class Main {
public static void main(String[] args){

Hero h1 = new Hero(); h1.name = "ミナト"; h1.hp = 100; Hero h2 = new Hero(); h2.name = "ミナト"; h2.hp = 100; if(h1.equals(h2) == true){ System.out.println("同じ内容です"); }else{ System.out.println("違う内容です"); } if(h1 == h2){ System.out.println("同じ内容です"); }else{ System.out.println("違う内容です");

//以下Heroクラス
public class Hero {
String name;
int hp;
}

【出力結果】
違う内容です
違う内容です

###補足情報(言語/FW/ツール等のバージョンなど)
ネットなどで確認する限りだと、
「==」はクラスに代入された値が同じであればtrueを表示。
「epuals」はメモリ上の保存位置まで同じであればtrueを表示。
と書いてあるように認識しました。

2つのインスタンスを使っているので、下がfalseになるのは分かるのですが、
全く同じ内容の上がfalseになるのはなぜでしょうか。
初歩的な内容で恐れ入りますが、ご教示頂けますでしょうか。

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

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

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

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

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

guest

回答3

0

「==」はクラスに代入された値が同じであればtrueを表示。

「epuals」はメモリ上の保存位置まで同じであればtrueを表示。

これはJavaではです。==は同一オブジェクトでだけtrueで、equalsは中身が等しければtrueです。

自分でクラスを作った場合、equalsで正しく判定してほしければ自分で実装する必要があります

なにもしない場合、Object.equalsリファレンス)が呼ばれて、「 x と y が同じオブジェクトを参照する (x == y が true) 場合にだけ true を返します。」

投稿2016/10/12 08:59

maisumakun

総合スコア145183

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

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

sakuman0

2016/10/12 15:30

ご回答有難う御座いました! 色々理解がずれていたようなので、諸々再確認したのですが、 以下のような理解であってますでしょうか。 【解釈】 まず、オブジェクトはインスタンスの属性が代入された状態だと再認識しました。 ※<http://nobuo-create.net/java-beginner-17/> 参照 APIのequals説明を見ると、比較対象が同じオブジェクトを参照する場合に trueを表示と記載されていました。 今回は「==」「equals」両方ともfalseと表示されたのですが、 ========= ・if(h1.equals(h2) == true){ ========= 上記は、オブジェクトを「属性が代入されているインスタンス」だと理解すれば、 h1とh2はメモリ上の別々の場所に保存されており、「違うインスタンス」となるので、 代入後に「違うオブジェクト」となり、falseになると解釈しています。 ========= ・if(h1 == h2){ ========= こちらについてですが、「==」は内容さえ同じであればtrueのはずがfalseになるのが気になります。 資料を模索して、以下のような解釈に至ったのですが、あってますでしょうか。 ・「==」は変数に代入されている値にのみ有効。 newすると使えない。 ・ オブジェクトを比較したいなら、「equals」を使うしかない。   但し、内容が同じというだけだとfalseになる。    http://javatechnology.net/java/if_string_equals/ ※ちなみに上記の資料を参照して解釈しました。
maisumakun

2016/10/13 00:26

Stringの場合は少し特殊で、「別な場所で作った同じ内容の文字列」が「同じオブジェクトになってしまう」ことがあります。ということで、Stringに==を使うと、同じ内容の文字列について、trueを返すこともfalseを返すこともあります。 また、new Stringで文字列を生成することも可能です(リテラルで書けばいいので、ふつうは行いませんが)し、もちろんそれを==のオペランドにすることもできます。
sakuman0

2016/10/13 06:30

参考書を進めていくとこれも少し載っているようでした。 String型の比較には==ではなく、equalsを利用しないといけないのですね。 次回以降質問をする際は、なるべく自己解決できるように、 単元の区切り程度までは参考書を進めた上で質問するようにします。 ご回答ありがとうございました。
guest

0

ベストアンサー

まだ回答を理解していないようですね。
まず基本的な話として、Javaにおいてはint,longなどのプリミティブ型以外はすべて参照型です。
参照型の変数にはその実体のオブジェクトが置かれている場所を示す値(参照値)が代入され、その値を使って実体にアクセスします。
以下はこれを理解した上で読んで下さい。

まず==は、両辺の変数が同じオブジェクトを指し示しているかどうかを判定する演算子です。内容がどうとかは全く判定しません。最も、同じオブジェクトを指していれば必然的に中身も同じですが。
newすると使えないわけではありません。ただし、そのnewしたオブジェクトと同じものを指す変数がほとんどの状況において存在しえないので、だいたいfalseになります。

equalsメソッドは、自分と引数として渡されたオブジェクトが「同じ」であるかどうかを判定するためのメソッドです。**何をもって「同じ」とするかはクラスの設計者が決める必要があります。**何も設計しなければ==での比較と全く同じ効果になります。設計に応じて、equalsメソッドをオーバーライドすることで、希望通りの比較ができるようになるのです。

例として出されたコードでは、2つのHeroオブジェクトを作り、名前をともに"ミナト"に設定し、HPを100に設定しました。しかしあくまでこれらのHeroは別個のオブジェクトです。別々のHeroに、同じ名前、同じHPを設定しただけで、別のものなのです。なので==での比較もfalseになるし、「同じ」の定義を==と一緒にしているequalsメソッドでもfalseになるのです。

投稿2016/10/12 15:40

編集2016/10/12 15:47
swordone

総合スコア20651

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

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

sakuman0

2016/10/13 09:42 編集

非常に丁寧な回答有難う御座います。 > まず==は、両辺の変数が同じオブジェクトを指し示しているかどうかを判定する ==の場合は、A書店に「JAVA入門書」という名称の本が2冊あったとして、 店頭に置いてある本と奥に保管してある本は内容は同じですが、 別々のオブジェクトなので違うもの(false)だと認識します、 という考え方だと認識しました。 > newすると使えないわけではありません。 newすると中身は値ではなく案内板になるので、trueにするためには、 比較対象の変数の中に同じ案内板が入っている必要がある。 しかし、オブジェクト化している以上はそれぞれが別の実体であるはずなので、 別の実体が同じメモリ格納先に入っているはずもなく、大概failsになると理解しました。 ※ややこしい書き方になりすみません。 > equalsメソッドは、自分と引数として渡されたオブジェクトが >「同じ」であるかどうかを判定するためのメソッドです。 > 何をもって「同じ」とするかはクラスの設計者が決める必要があります。 参考書のページを進めたらHeroクラスでObjectクラスの equalsメソッドをオーバーライドさせる話が載っていました。 > (※equalsは)何も設計しなければ==での比較と全く同じ効果になります 参考書などを見る限りでは、equalsメソッドは、比較対象オブジェクトの メモリ保管先が違ったとしても、内容さえ同じであれば、同一のものとみなすと書いてあり、 同じ実体のみをtrueと捉える[==]とは逆になるように見受けられます。 教えてもらっている中、些細な記載違いでしたら申し訳ありません。 ==================================== ※参考書を一部抜粋 等価(equals)の判定 さしている2つのものが「同じ内容」であること (同じアドレスを指していなくてもよい) Hero h1 = new Hero("ミナト"); メモリ:3345番地格納 Hero h2 = new Hero("ミナト"); メモリ:9191番地格納 このとき、h1 != h2 たが、 h1.equals(h2)である。 ====================================
swordone

2016/10/13 12:24

2点目のnewについて newした際には「新たなオブジェクト」(この場合は本)が生成され、その新たなオブジェクトを指す案内板が返ってきます。これと別の変数とで"=="で比較してtrueになるためには両辺が同じ場所を指す案内板である必要があるわけですが、この場で新たに作ったオブジェクトを指す案内板がそれ以前に存在するはずがありません。よっぽど変な書き方をしない限り、newしたオブジェクトを"=="の比較の俎上に載せてtrueになることはありえません。 ラストのequalsについて これはあくまでそういう比較のルール付け(すなわちequalsのオーバーライド)をしたあとでの話です。今のあなたのコードでは比較のルールを付けていない("=="での比較と同じ)ので、falseになります。
sakuman0

2016/10/13 15:14

> この場で新たに作ったオブジェクトを指す案内板が > それ以前に存在するはずがありません。 確かにその通りですね。 非常に分かりやすいです。 有難う御座います。 > これはあくまでそういう比較のルール付け > (すなわちequalsのオーバーライド)をしたあとでの話です。 失礼な質問をしてしまいすみません。 参考書の抜粋は既にepualsがオーバーライドされていたんですね。 APIにも「(※equalsは)比較対象が同じオブジェクトを参照する場合にtrueを表示」 という感じの説明があったので、オーバーライド以前の挙動はどちらも 「同一のオブジェクトを比較した場合にtrueと返す」と理解しました。 この度は誠に有難うございました。
guest

0

Heroクラスのequals()をoverrideしてあげていないからです。
Object#equals()の仕様はここに記載があります。

Effective Javaにある規約では、equalsをオーバーライドする時、次の内容を守るようにしろとの記載があります。

1.It is reflexive: For any reference value x, x.equals(x) must return true.
2.It is symmetric: For any reference values x and y, x.equals(y) must return true if and only if y.equals(x) return true.
3.It is transitive. For any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) must return true.
4.It is consistent. For any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified.

投稿2016/10/12 09:00

moonphase

総合スコア6621

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

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

sakuman0

2016/10/12 15:33

ご回答ありがとうございます! equals を使う場合の true の判断基準はオーバーライドにより更新できる旨理解しました。 詳細については、資料などから確認させていただこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問