• ベストアンサー

JavaにはなぜGO TO 命令がないのでしょうか?

皆さん教えて下さい。私はCOBOLを長年手がけ、最近Javaを勉強している者です。 JavaにはなぜGO TO 命令がないのでしょうか? IF ネストというのは、わかりにくく、私は昔から嫌っておりました。 ところがJavaにはGO TO 命令が無いため、いやでもIF ネストを使わねばならないようです。 それともわかりやすく効率的なコーディングが別にあるのでしょうか?? 3択の問題で、下記AはJavaの教科書的コーディングです。3択だからまだしも複雑になると、IFネストはわかりにくいと私は思います。 下記Bはわかりやすいですが、無駄な処理が発生し、良くないコーディング例です。 下記CはCOBOLコ-ディングで、GO TOが使えるため、人間が読んでわかりやすく、処理効率もいいです。 ●この点Javaをやっている皆さんどうお考えですか??? ------------------------------------------------------------------------------------ A<教科書的サンプル> if(a > 0){ System.out.println("aは正の値です。"); }else if(a == 0){ System.out.println("aはゼロです。"); }else{ System.out.println("aは負の値です。"); } ------------------------------------------------------------------------------------ B<if ネストを嫌った サンプル> if(a > 0){System.out.println("aは正の値です。");} if(a == 0){System.out.println("aはゼロです。");} if (a < 0){System.out.println("aは負の値です。");}   処理効率悪く、良くないプログラム例 ------------------------------------------------------------------------------------ C<COBOL なら> IF a  >  0 DISPLAY "aは正の値です。"    GO TO OWARI. IF a  =  0 DISPLAY " aはゼロです。"   GO TO OWARI. IF a <  0 DISPLAY " aは負の値です。" . OWARI. .    GO TO 命令がある故に効率的 IF 構文の終わりと、OWARI の後ろにピリオドがあります。 ------------------------------------------------------------------------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

goto は自由すぎるので, 「うまく使えば」強力なんだけどうまく使えないとプログラムがとてつもなく読みにくくなってしまいます. ということで, 今どきの言語では「管理した goto」を導入し, 自由すぎる goto の使用頻度を極力減らす (あるいは goto そのものをなくしてしまう) のが普通です. その「管理した goto」が break や continue などです. あと, 確かに if~else if~ というのは構文的に「if のネスト」なんだけど, 多くの場合そのようには意識しません. この全体を見て「多方向分岐という構造である」と認識します. 逆に C や Java に慣れた目から見ると, その COBOL の書き方の方が「読みにくい」と映ることでしょう. つまり, C や Java のプログラマにとって「else if」は見慣れた構造なので特に悩むことなく一目で「多方向分岐」と判断します. ところが COBOL の書き方では先頭のキーワードがすべて「IF」なので, すべての場合が背反であるかどうかを判定するためには文の最後まで見なければなりません. そこにコストがかかるということも念頭に置かねばなりません. いずれにしても「読んでわかりやすい」かどうかは「読む人がその言語にどのくらい慣れているのか」ということを抜きにして考えても無意味です. 以下余談: C に goto は存在しますよ>#1. C++ にだってある. Java の場合 goto は予約語ではあるけど機能を持っていないんだっけな? 余談その2: 「else if」構造に対する特殊な構文を持っている言語も存在します. 余談その3: 「goto の自由度」という意味では Pascal が最強に近いかなぁ.

その他の回答 (18)

回答No.9

>buriです。確かに言われてみればそうですね。else if を、何と >いうか1つの語句のように捉えるというか(うまい表現が思いつき >ません)、慣れてしまえばそうなのかもしれません。 >各自の育 >った環境による主観かな?と思わないでもないです。> そうかも >しれませんね。COBOLの、特に客に密接したプログラマは、仕 >様書を忠実にプログラムに置き換えるという発想が強いですからね。 では、「COBOLの、特に客に密接したプログラマ」以外のプログラマは仕様書を忠実にプログラムに置き換える発想が弱いというということでしょうか? 単に、設計者の仕様書の意図が正しくプログラマに伝わっていないだけ、ということはないでしょうか?(設計書の形式、設計者の能力不足、プログラマの認識不足などいろいろ考えるべきところはあるかと思いますが)

回答No.8

public static void main(String[] args) { System.out.println(Kyuyo("男",40)); System.out.println(Kyuyo("男",39)); System.out.println(Kyuyo("女",40)); System.out.println(Kyuyo("女",39)); System.out.println(Kyuyo("男女",40)); } private static String Kyuyo(String sex , int age ){ String result = null; if ( sex.equals("男") && age >= 40 ){ result = "1号俸"; } else if ( sex.equals("男") && age < 40 ){ result = "2号俸"; } else if ( sex.equals("女") && age >= 40 ){ result = "3号俸"; } else if ( sex.equals("女") && age < 40 ){ result = "4号俸"; } else { result = "二丁目にどうぞ"; //elseブロックなしでも動きます } return result; } ・男で40歳以上は、1号俸とする。 ・男で40歳未満は、2号俸とする。 ・女で40歳以上は、3号俸とする。 ・女で40歳未満は、4号俸とする。 ↑をJavaで記述するとこんな風になるかと思うのですが、わかりにくく処理効率が悪いようには見えないのですがいかがでしょ? 各自の育った環境による主観かな?と思わないでもないです。

buri5000
質問者

お礼

buriです。確かに言われてみればそうですね。else if を、何というか1つの語句のように捉えるというか(うまい表現が思いつきません)、慣れてしまえばそうなのかもしれません。 >各自の育った環境による主観かな?と思わないでもないです。> そうかもしれませんね。COBOLの、特に客に密接したプログラマは、仕様書を忠実にプログラムに置き換えるという発想が強いですからね。

回答No.7

いいたいことはほとんど他の回答者さんが言ってくださっているので、ぼちぼちその回答に対するスレ主さんの「まとめ」or「意見」を聞いてみたいところです。

buri5000
質問者

お礼

buriです、皆さん有り難う、意見は1000文字以下でないといけないんですね。縮めて・・・ 皆さんから色々なご意見が出たので、構造化というような大きなテーマはさておき、goto文がないと、ifnestにせざるを得ず、いかに読みにくいかという言う点だけに絞って述べたいと思います。 さて、if nestが慣れているからわかりやすいというご意見を見ると、慣れればそんなものかと考えるほかありません。 (注)私のサンプルAで適切なインデントがされてないのは、この投稿欄では、無駄と見られた空白文字は削除されることに原因がありそうです。 1)さてCOBOLは元々英文ライクで、仕様書をそのまま記述する考えに立っています。 次のような客先仕様があったとします。無論デフォルメしてありますが。 ある官庁にて給与を以下のように決める。 ・男で40歳以上は、1号俸とする。 ・男で40歳未満は、2号俸とする。 ・女で40歳以上は、3号俸とする。 ・女で40歳未満は、4号俸とする。 これをCOBOLでコーディングすると、以下のようにするのが、一番バグの入りにくいプログラムです。 IF (SEX = MALE) AND (AGE GREATER OR EQUAL 40) MOVE 1 TO HOKYU GOTO OWARI. (← ピリオドあり) IF (SEX = MALE) AND (AGE LESS 40) MOVE 2 TO HOKYU GOTO OWARI. (← ピリオドあり) IF (SEX = FEMALE) AND (AGE GREATER OR EQUAL 40) MOVE 3 TO HOKYU GOTO OWARI. (← ピリオドあり) IF (SEX = MALE) AND (AGE LESS 40) MOVE 4 TO HOKYU . (← ピリオドあり) ERROR-SHORI. ・・・・・ OWARI. 即ち、人間の頭は仕様記述の際に、女は男のelseだとは考えません。 どんな官庁や民間の規則でも、上記仕様書のように書かれているはずです。 COBOLはそれをそのままコーディングできる訳です。 その際にIFと GO TOが必須となると思います。 昔のCOBOLの時代にも、IF ELSEのネストでコーディングする人は少数いました。しかしこんなプログラムは仕様変更や追加を他人がやる場合には困ったものでした。

  • foxa-gogo
  • ベストアンサー率44% (38/85)
回答No.6

gotoは、ソースの可読性を下げることがあり、実際の研究でバグの原因となることが多くあることが確かめられたため、javaではサポートしないことになったそうです。 また、こちらはちょっと専門家じゃないので自信がないのですが、コンパイラによる最適化を十分に引き出す上でも、gotoの使用は問題になるんじゃないかと思います。(コンパイラがソースを理解することが困難になり、最適化が一部使えなくなる)

  • dyna_1550
  • ベストアンサー率34% (122/353)
回答No.5

buri5000さんは、構造体を非常によく理解されており、goto文が諸刃の剣で あることも理解しているとお見受けします。 Javaの生い立ちは、前身にC++があり、言語仕様が非常に自由でした。 特に多重継承やテンプレート、オーバーライドを駆使すると、見事なまでの シンプルなプログラムが出来上がりますが、一歩間違うと、デバッグに 明け暮れ、効果なツールを投入しないとプロジェクトが成り立たない事態 になったり、メモリリークが時間差で訪れ、潜在バグに怯える日々を過ごす 経験を持つ人も少なからずいると思います。 それらを、言語仕様そのものから排除しようとしたのがJavaと思ってます。 Javaの初期の頃は、仕様がかなり限定され、いままでのプログラミングの 知識ではなかなか物ができあがらず苦労しました。 ちょうど、goto文がなく、仕方なくif文を使うburi5000さんのように。 ただし、Javaはオブジェクト指向とデザインパターンを学ぶのには よくできていると思います。 オブジェクト指向は、実装ではなく、設計に重点がおかれます。 つまり、きれいなソースを書くというよりも、よいオブジェクトを設計する ということが大切な考えとなります。 よいオブジェクトが出来上がると、再利用性(拡張や作り変え)に威力を 発揮します。 ちゃんとしたインタフェースを持てば、内部の実装は適当でも許されます。 それが隠蔽の考え方です。 今回の例では、条件分岐のみが例に挙がっていますので、オブジェクトの 設計が困難なので、Javaの良い面が発揮できません。 いったい、「何の目的」で、「誰が」判断するのか、などの分析設計を しっかり行うと、cobolとJavaの違いが出てくると思います。 オブジェクト指向は、綺麗なソースをパパっと作ることには向いては いないように思います。 例えば、単純なコーディングであれば、cobolよりも、perlやphpで済ます技術者もいると思います。

noname#94983
noname#94983
回答No.4

うーん。既にオブジェクト脳に侵されているせいか、質問文のサンプルを見たところ、A<教科書的サンプル>がもっともすっきりしていて、C<COBOL なら>が一番わかりにくいサンプルに見えてしまったな。 1行に書いてあるからわかりにくいんで、きちんとJavaの標準的なインデントでコーディングすれば、Aの書き方は一目瞭然、実にすっきりと見ていて美しい。 それと、よく見たらどれも「IFのネスト」にはなってないな。単なる「IFの連結」だ。ネストというのは「入れ子構造」のことだろう。こういうのでないかね。 if (flag){  if (flag){   if (flag){    // hogehoge   }  } } ちなみに、GOTOはないが、ラベルはある。Javaでは、なぜか意外に知られてないんだけどね。だから、こういう本来の入れ子構造なら、一番奥の階層から一気にトップの階層に戻ったりできる。 mylabel: if (flag){  if (flag){   if (flag){    break mylabel; // 一番外側のifの外に抜ける   }  } } GOTOはなぜなくなったかというと、「できあがったコーディングのメンテナンス性の悪さ=品質の悪さ」が、もはやどうにもならないレベルになってしまったからだろうと思う。たとえば、数万行のソースコードで、GOTOを駆使して書かれた状態を想像してほしい。オレなら、そんなソースコードのメンテナンスは死んでもやりたくない。GOTOはいわば「制御構文の例外者」だ。美しい制御構造を破壊する。構文の美しい構造さえ見ていればすべてが整然と理解できるGOSUBに対し、GOTOは、どんなに構文の構造を見てもそれだけでは理解できない。あちこちに穴を開けてジャンプし、美しい構造を破壊する。こんな醜悪な機能はない、とオレは思う。 そして、既にGOSUBさえない言語がオブジェクト指向では当たり前となった。オレは心から安堵する。もはや、あのGOTOだらけの悪夢のようなスパゲティコードを読むことはない。悪夢にうなされずにすむだけでもGOTOのない世界は、いい。

  • Dxak
  • ベストアンサー率34% (510/1465)
回答No.2

う~ん、事務用プログラムと言われるCOBOL 同世代で、有名な言語と言えば、BASIC、FORTRAN これらは、非構造化プログラムと言われます これに対し、構造化プログラムと言われる C、Pascal、Java等の系列では、gotoは、あっても使用を避ける もしくは、命令そのものを抹消すると言う傾向にあります 構造化プログラミング - Wikipedia http://ja.wikipedia.org/wiki/%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0 まぁ、「goto論争」を読むと判ると思うけど・・・ goto文は、質問者さまが言う、自由に扱える故に、そのメンテナンス等、デバッグ効率を、著しく落とすと言う欠点から、嫌われる傾向にあるという話 しかしです 日本では、オブジェクト指向などと同じく、他人の作ったものを読解して、弄り回すと言う考えが、あまり企業内に無いため、こう言う構造論の話は、あまり役に立ってない!って話は、聞いてますけどね^^;

回答No.1

●構造化プログラミングとGOTO  えっと、もう何十年も昔になるでしょうか。  構造化プログラミングが提唱され、COBOLやFORTRANといった古い言語に見られたGOTOを排除する動きが起りました。GOTOがあるとソースの流れが途中で寸断され、流れがつかみにくいコードになるという考えが基礎になっており、サブルーチンをベースに流れるように記述するのがポイントと言っていいでしょう。  Javaの基礎となったC言語は構造化言語の代表的なもので、GOTOがありません。この考えは大きく広がり、FORTRANも構造化言語になって久しいです。GOTO自体を知らない人も多いのではないでしょうか。 ●ifのネスト  ifのネストはたしかに不細工ですよね。構造化言語では、複数分岐をサポートしていることが一般的で、Javaにもswitch文があります。これは条件によって3つ以上の条件処理を可能にしているものです。詳しくは以下をご覧ください。 http://www2.ocn.ne.jp/~notes/java/java9.html  さて、このページにもありますが、GOTOの代わりに、switch文ではbreak文が併用されます。 「なんだGOTOと一緒じゃないか」 と思われるかも知れませんが、GOTOがどこへでも飛べるのに対し、breakはその分岐やループを抜けるためだけに使われます。  

関連するQ&A