これからJavaを始めようという人の為の超入門サイトです。丁寧、簡単にこだわった解説なので初心者にぴったりですtwitter2facebook0hatenabookmark1423linesponsored linkもくじ 初めはStringって何なのかよく分からないまま、ただ単に文字列を保持する変数だと思って使う人が多いと思います。かく言う私も、Stringってすんごい基本的な変数なのに、なぜ基本データ型(プリミティブ型)に含まれていないのかな?なんて思ったクチでした。 そもそもStringと、基本データ型(boolean,byte,char,short,int,long,float,double)には見た目の決定的な違いがありますよね。何かというと基本データ型は全部小文字だけど、Stringは頭文字が大文字だと言う事。なぜStringは頭文字が大文字なのかと言えばStringは 基本データ型というのはJavaのまさに基本データとして元々存在している型です。一方、クラス型というのはクラスでそのオブジェクトについて定義することで使えるようになる型です。 つまり、 あなたが書いているクラスから他のパッケージの中にあるクラスを使おうと思ったら、普通は、パッケージ名からフルネームで「java.lang.String」と書くか、あるいはそのパッケージなりクラスなりをimportしてしまう必要があるのですが、Stringクラスに関してはimportせずとも「String」だけで通じるようになっています。なぜなら「java.lang」パッケージはJavaプログラミングにおける必須的なクラスが詰まっているので、初めからパッケージごとimportされている状態らしいです。だから「String」だけで普通に使えるわけです。 String型の変数を宣言して、文字列を代入するのは簡単なので誰でもやったことあると思います。 こんな風に簡単にできますよね。けど、これって実は裏があるんですね。 上記でも言いましたが、Stringは「java.lang」パッケージの中にあるStringクラスで定義されているクラス型変数です。クラス型の変数というのは言い方を変えるとオブジェクトです。 オブジェクトを作る時は普通は 本来なら、文字列”あいうえお”を保持するStringオブジェクトを作るには、 こうやってnew演算子を使って、Stringクラスのコンストラクタを呼ばないとオブジェクトは作れません。文字列をコンストラクタの引数に渡すことで、その文字列を保持したStringオブジェクトが作られるわけです。 しかし、この形は実はすごい二度手間なことをしているんです。 プログラムソースの中で、ダブルクォーテーションで囲われた文字列を「 それを踏まえると、この形は、引数に渡した”あいうえお”自体がStringオブジェクトなので、Stringオブジェクトを作るために引数にStringオブジェクトを渡していることになりますよね。二度手間とはまさにこのことです。 しかも全く同じ文字列を保持したオブジェクトをもう一つ作ってしまっていることになり、引数に渡した”あいうえお”オブジェクトは結果的にほったらかし状態になってしまいます。メモリの無駄使いです。 なので、String型のオブジェクトを作る際は、 これで正解なんです。 これは一体何をしているのかと言うと、String型の変数sに、Stringオブジェクトである”あいうえお”の参照値を代入しているわけです。”あいうえお”っていうのは文字列リテラルなのですが、その実体はコンパイラが勝手に作った”あいうえお”オブジェクトの場所を示す参照値なんです。 その参照値をString型変数sに代入しているわけです。これなら余計なオブジェクトは作らずにコンパイラが文字列リテラルから勝手に作ってくれたStringオブジェクトをそのまま使えますね。 Stringクラスの中身を見たことありますでしょうか?面白いので暇な人は覗いてみたらいいと思います。 Stringクラスのインスタンスフィールドの一つに、というのがあります。これは何かというとchar型変数の配列です。ちょっと余談ですが、僕は配列の宣言の表記の仕方は、こっちの方が分かりやすくて好きです。余談でした。。 charというのはunicodeで表される文字1文字を保持する基本データ型の変数型です(参考: なるほど!と唸りますよね。charなんて一体どんな時に使うねん!一文字でもStringを使えばいいやん!と思っていましたが、Stringというのはchar型の配列をフィールドに持っているからこそ、文字列を保持できるんです。charあってのStringなんですね。charに謝りたい気持ちでいっぱいです。 そしてもう一つ、重要なフィールド(パラメータ)を紹介します。 このint型変数 Stringの文字数と言えば、このメソッドは使ったことあると思います。↓出ました。length()です。このインスタンスメソッドは、「return count」しています。「this」は省略されていますが、省略せずに書くと、ということです。 つまり、length()は、このインスタンスが保持している文字列の文字数を戻り値として返すメソッドなんです。だから、これを実行すると、言うまでもないですが、となるわけです。 ちょっと関係ない話になりますが、「length( )」とよく似たのに「length」があります。( )があるかないかの違いです。 この「a.length」の形です。これで「3」と出力されます(配列変数aの要素数)。 「length( )」はStringクラスのインスタンスメソッド、「length」は、配列オブジェクトのパラメータ??みたいなもんです。なんだか曖昧で申し訳ないのですが、片やメソッド、片やフィールドだと考えれば、( )の有る無しにも納得がいきますね。(真相をご存じの方いらっしゃいましたら、ぜひ教えてもらいたいところです。。) Stringクラスのメンバメソッドは、length( )だけではなく、いろんなメソッドが定義されています。 まずは、個人的に非常によく使うstaticなメソッドを一つ。このvalueOfメソッドは、引数に受け取ったint型の値をStringに変換して戻り値として返します。 staticなメソッドなので、このように Androidアプリのプログラミングでよく、TextViewにsetText( )して文字を表示するのですが、このsetText( )メソッドはStringしか受け取ってくれません。だからもし数字を表示したい時は、intやdoubleのままではsetText( )の引数に渡せません。 そんな時に、このStringクラスのvalueOf( )メソッドが役立ちます。ちなみにこのメソッドはint型の他にも、基本データ型全種及びオブジェクトも引数に受け取ることができるようにオーバーロードされていて、渡せば何でもStringに変換してくれます。(参考: もう一つ、今度は便利なインスタンスメソッドをご紹介。 このsubstringメソッドは、そのインスタンスが保持する文字列から、一部分を切り取って新たな文字列にして戻り値として返します。 これで、sの保持する文字列(あいうえお)の1番目の文字から3番目の文字までを切り取った文字列を返して、tに代入してくれます。引数は1と4ですが、切り取られるのは1番目の文字から3番目の文字までです。第一引数beginIndexはその値を含みますが、第二引数endIndexはその値を含まないんです。ちょっとややこしいですね。さらに、この何番目というのがちょっとやっかいなのですが、0番から始まります。つまり0番目が”あ”、1番目が”い”、・・、4番目が”お”になります。 結果、tには”いうえ”が入ることになります。引数の1,4を見ると、直感的には”あいうえ”になるように思えてしまいますが、そうではないのでご注意を。 valueOfメソッドと、substringメソッドを使うちょっと強引?な例を挙げます。例えば、生年月日を表す19770101というint型の値があって、それを”1977年01月01日”に変換するとしましょう。 これでstrBirthday2には、”1977年01月01日”という文字列が入ります。”01″を”1″に変えたい場合は正規表現を使ってちょちょいのちょいとできますが、それはまたの機会に。。やろうと思えばif文を使って簡単にできますよね。もしyearの1文字目が0ならば・・、ってな具合に。やりたい人はやってみて下さい。 とりあえず2つのメソッドを紹介しましたが、Stringクラスには便利なメソッドがたくさん定義されています。上にも書きましたが、 ちょっと初心者がつまづきやすいポイントだと思うのですが、こちらをご覧下さい。 この時点で、sは何になっているでしょうか? ”いうえ”だと思った方は、残念ながら素人確定です。。 substringメソッドはインスタンスメソッドなので、どうしてもそのインスタンス自体をいじるようなイメージがあるのですが、それは誤解です。このメソッドはインスタンスメソッドのくせに、全く別のインスタンスを新たに作って、戻り値として返すようになっています。 つまり、s自体にはなんら手を加えることなく、sの1番目から3番目までの文字列を保持する新たなStringインスタンスを作って、戻り値として返すのが、このsubstringメソッドなんです。 なので、 これだと、sには何も手を加えていないので、sは”あいうえお”のまんまです。二行目はただ単に”いうえ”を保持するStringインスタンスを別で作っただけで、それをどこに代入するわけでもなく放置しているだけです。。(こんなわけの分からないコードは決して書かないようにしましょう。) インスタンスメソッドで、別のインスタンスを戻り値として返すというのはなんか変な感じですが、なぜこんなことするかと言うと、そもそもStringというのは、そのインスタンスが保持する文字列を書き換える事ができないからです。つまり、インスタンスメソッドで自分自身のフィールドである文字列を操作することはできないんです。 上述しましたが、Stringクラスは文字列を保持する為に、char配列を使っています。 これが、Stringクラスの文字列を保持する為のフィールドなんですが、見ての通り、「final」という修飾子がついています。これは、上書き禁止を表す修飾子です。「final」が付いているということは、このchar配列は一度初期化したら書き換えることはできないわけですね。つまりStringは文字列を一度保持したら、二度と書き換えることができないということです。 なので、substringメソッドだけでなく、Stringクラスで定義されている、文字列を操作して戻り値として返しているようなメソッドは全て、新たなインスタンスを作ってそれを戻り値として返しているというわけです。こんなところで。