プロが教えるわが家の防犯対策術!

こんにちは、Stringクラスのlengthメソッドについて質問させてください。

今まで配列のlengthは、宣言時に長さが決定するからメソッドではなく、finalフィールドで十分。
ArrayListだとかは長さが変わるからメソッドという意識を持っていました。
(カプセル化の概念とも関わりますが)

先日その話しをしていたら、「でも文字列(Stringオブジェクト)の長さも不変だよね。」と言われました。
確かに文字列の長さは不変なのに、長さの取得にはメソッドを使っています。

言語仕様として一貫性を持たせるなら、配列もlengthメソッドにするか、文字列をlengthフィールドにしたほうが綺麗だと思うんです。

Stringクラスのソースコードを見ていたら、文字列の長さは内部的に
private int count; と宣言されていました。
そして、lengthメソッドは return count; しているだけでした。

ただ、このcountフィールドに値を代入しているのはコンストラクタ内だけだったので、
public final int length; とすれば、良かったのでは?と思いました。

この考えについて、
それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。

よろしくお願致します。

A 回答 (5件)

あくまで想像ですが・・・



長さを問い合せる場合、括弧付きの「length()」である方がオブジェクト指向
らしい方法と思います。

配列のlenghthは、あくまでフィールドです。
つまり、いくつ配列に格納したか、ではなく、配列として準備した個数を格納
しているにすぎません。

Stringの長さが「不変である」というのは、Stringの性質ではなく、たんに
そういうクラスを作っただけのことなので、結果論からfinalにするのは
設計上正しいとは思えません。
可変のStringクラスだってあってもいいのでは?
    • good
    • 0
この回答へのお礼

説得力のある説明、ありがとうございます。

もうひとつ質問になってしまうんですが、
配列はlengthフィールドで長さを取得しますが、設計の段階でこれをlengthメソッドにするわけにはいかなかったんですかね?

そのほうがオブジェクト志向らしくはなりませんか・・・?

お礼日時:2008/06/11 18:51

>この考えについて、


>それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。

歴史的背景については分かり兼ねますが、ここのカテにて歴史的に繰り返されている質問の一つであることだけは周知済みです。

「配列変数のlengthプロパティは、どうしてそのまま参照できるのですか?」
http://oshiete1.goo.ne.jp/qa2491628.html

「String(文字列)と配列の length の違いについて」
http://oshiete1.goo.ne.jp/qa3519349.html


>ということは1.0の時点ではlengthをフィールドにしても問題はなかったと思うんですが・・・

以前ググった時には、上記のような内容をJavaHouseのメーリングリスト内でチラッと見かけました。ただ、「なんで?」とか「どうして?」などのような思想に関わってくるものに関しては、国内のサイトだけで理解しようとするのは非常に困難であるように思います。
    • good
    • 0

ANo.2です



指摘を受けてStringクラスを見てきました。そもそもcountフィールド自体が
private final int count;
と宣言されていますね・・・

finalか、privateのどちらかなら、間違った変更を防止するため、と言えるのですが、finalだけあれば外からの変更を防止できるはずなので、public finalとしてもいい気がします。

ただ、直接参照させないときの利点について、仕様変更のときのことが考えられるんじゃないかなぁ、と思ったわけです。
たとえば、今まではStringクラスは内部に文字数と同じだけのChar配列を持っていましたが、新たな機能を追加するにいたって、1文字表すのにCharを2つ使うようになったとか、なんかうまい例が思いつかないけど・・・
とにかくChar配列の大きさと文字の長さが食い違うような状況になったときにメソッドにしておけば変更できるから。ということではないでしょうか
    • good
    • 0

StringクラスはCharSequenceインタフェースを実装しています。


length()メソッドはここで宣言されているのですが、
上記のインタフェースを実装しているのはStringクラスだけでなく
StringBufferクラスも実装しています。

StringBufferクラスは可変文字列なので
そちらの方にも対応させる為ではないでしょうか。

参考URL:http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/ja …
    • good
    • 0
この回答へのお礼

ありがとうございます

確かにご指摘の通りStringクラスはCharSequenceインターフェースを実装しています。
しかしそれは1.4からの話しであって、1.3まではありませんでした。

恐らく標準ライブラリに正規表現のクラス(PatternやMatcher)を導入するために、追加したインターフェースだと思います。
ということは1.0の時点ではlengthをフィールドにしても問題はなかったと思うんですが・・・

お礼日時:2008/06/11 18:44

自信を持ってはいえませんが・・・


まず、String#replaceAll(String, String)というメソッドがあるので、
Stringの文字の長さは可変だと思います。
ですので、finalには出来ませんよね

それではprivateにするのはなぜかというと、フィールドを直接よびだして勝手な値を代入されるという危険性を避けるためです。
要はバグ防止ということでしょうか。
フィールドのカプセル化 で検索してみると色々でてきますよ

参考URL:http://milkyway.merseine.nu/100java/Java/Java997 …
    • good
    • 0
この回答へのお礼

ありがとうございます。

カプセル化については理解している(つもり)なので問題ありません。

指摘にあったString#replaceAll(String, String)メソッドなんですが、
内部的に新しいStringオブジェクトを生成しているのであって、長さを変えているわけではないと思うんですが・・・?

お礼日時:2008/06/11 18:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!