JavaのStringクラスまとめ[Java入門]

2025.6.16 不適切な説明があるとの指摘を受け、コードと記事本文を一部削除しました。

## はじめに

こんにちは。
プログラミング初心者Wakinozaと申します。
Java勉強中に調べたことを記事にまとめています。

十分気をつけて執筆していますが、なにぶん初心者が書いた記事なので、理解が浅い点などあるかと思います。
記事を参考にされる方は、初心者の記事であることを念頭において、お読みいただけると幸いです。
間違い等あれば、指摘いただけると助かります。

## 対象読者

- Javaを勉強中の方
- Java Silver試験を勉強中の方

## 目次

1\. Stringクラスとは
2\. Stringクラスの特徴1: イミュータブル
3\. Stringクラスの特徴2: コンスタントプール
4\. Stringクラスの主なメソッド

## 本文

### 1\. Stringクラスとは

Stringクラスは、文字列を扱うクラスです。
内部では文字の並びとして表現され、char型の文字の配列として扱われます。

Stringクラスのインスタンス生成方法は、主に２つあります。

#### 1\.「new」でインスタンスを作る

文字列はプリミティブ型ではなくクラスであるため、newキーワードを用いてインスタンスを作成します。

```Java
String str = new String("abcde");
System.out.println(str); //結果：abcde
```

#### 2\. 「"(ダブルクォーテーション)」で囲む

Stringクラスには、より簡易にインスタンスを生成する仕組みがあります。
具体的には文字列リテラルを「"」で囲むだけで、自動的にStringクラスのインスタンスが生成されます。

```Java
String str = "abcde";
System.out.println(str); //結果：abcde
```

特別な理由がない限り、2の「"」で囲む方法が一般的です。
その理由は、「"」で囲むと「コンスタントプール」によってメモリリソースを抑えることができるためです。
「コンスタントプール」は、後ほど説明します。

Stringクラスは、プログラム中で多用されるため、「イミュータブル」と「コンスタントプール」という２つの特徴を持っています。
次の節で、２つの特徴をそれぞれ説明していきます。

### 2\. Stringクラスの特徴1:イミュータブル

イミュータブルであることが特徴の一つです。

オブジェクトには、フィールドの値を後から変更できるもの(可変:ミュータブル)と、変更できないもの(不変:イミュータブル)があります。

Stringクラスは、不変のイミュータブルなクラスです。そのため、一度インスタンスが生成されたら、その内容を後から変更することはできません。String型変数へ値を再代入した場合は、変数の指し示すインスタンスが変化するのではなく、変数の中身が新しいインスタンスへの参照に置き換わります。

### 3\. Stringクラスの特徴2: コンスタントプール

もう一つの特徴は、メモリを効率よく使うためのコンスタントプールという仕組みです。

文字列は、コードの中でも特に多用されるものの一つです。そのため、むやみやたらと文字列が生成されると、メモリリソースを圧迫する可能性があります。
メモリ問題を解決するため、Stringクラスは「コンスタントプール」という仕組みを持っています。

「コンスタントプール」は、同じ文字列のデータを再利用する仕組みです。

文字列リテラルを「"」で囲んでStringインスタンスを生成した場合、メモリ上のコンスタントプールという領域に格納されます。この時、すでに同じ文字列が格納されていた場合は、既存のインスタンスへの参照を自動で使い回します。
以下のコードをご覧ください。

```Java
String c = "あいうえお"; //④
String d = "あいうえお"; //⑤
boolean e = c == d     //結果：true
```

String型変数cとdが、同じ文字列を別々に宣言しています。別々に宣言されているため、２つは別のインスタンスのように見えますが、そうではありません。
⑤で変数dを宣言した時点で、コンスタントプールには同じ文字列が既に格納されています。そのため、すでに格納されているインスタンスへの参照が自動で再利用されます。
その結果、変数cと変数dは、同じインスタンスへの参照を格納している状態になります。参照が同じであるため、「==」で等値判定を行うと結果はtrueとなります。

参照を再利用すると、同じ参照を持つ別の変数にまで変更の影響が出るのではと心配する方もいるかもしれませんが、大丈夫です。
先ほど述べたようにStringクラスはイミュータブルです。ある変数の内容を変更しても、同じ参照を格納している別の変数の内容は変化しません。
もしもStringがミュータブルだったら、コンスタントプールで同じインスタンスを使い回してしまうと、ある変数で変更した内容が意図せず他の変数にも影響を与えてしまいます。このような状態であれば、コンスタントプールの仕組みは実現できないでしょう。
Stringクラスにイミュータブルな特性があることによって、コンスタントプールというメモリ節約機能が実現できたのです。

ちなみに、newキーワードでインスタンスを生成した場合は、コンスタントプールとは別のヒープ領域にデータが格納されるため、参照が再利用されることはありません。
どうしても参照を再利用されたくない場合は、newキーワードでインスタンスを生成すると良いでしょう。

### 4\.Stringクラスの主なメソッド

次にStringクラスの主なメソッドについてまとめます。
今回紹介するのは、以下メソッドです。

- charAt
- concat
- contains
- equals
- indexOf
- intern
- length
- repeat
- replace
- substring
- toUpperCase
- toLowerCase

#### 1\.charAt ： 指定インデクスの文字を返す

public char charAt(int index)

- 指定されたインデクスの文字をchar型で返す
- インデクスが負の値か、文字列の長さ以上の場合は、IndexOutOfBoundsException がスローされる

```Java
String str = "aiueo";
char c = str.charAt(2);
System.out.println(c); //結果：u
```

#### 2\.concat : 文字列同士を連結する

public String concat(String str)

- 引数で指定された文字列を、文字列の最後に連結する

```Java
String str = "あいうえお".concat("かきくけこ");
System.out.println(str); //結果：あいうえおかきくけこ
```

#### 3\. contains : 指定の文字列を含んでいるか判定する

public boolean contains(CharSequence s)

- 文字列が、引数で指定された文字列を含む場合にtrueを、含まない場合はfalseを返す

```Java
String str = "appleorangemelon";
boolean b = str.contains("orange"));
System.out.println(b); //結果：true
```

:::note info
CharSequenceとは、文字の並びを表現するためJava.lang.CharSequenceインターフェースのこと。CharSequenceは、Stringクラスの他にStringBuilderクラスやStringBufferクラスも実装している。containsメソッドは引数にCharSequenceを受け取ることで、Stringクラス以外にもStringBuilderクラスやStringBufferクラスのデータも受け取れる仕様になっている。
:::

#### 4\. equals : 文字列が等しいか判定する

public boolean equals(Object anObject)

- 指定されたオブジェクトがこの文字列に等しいStringを表す場合はtrue、それ以外の場合はfalseを返す
- Stringクラスは参照型であるため、文字列が等しいかどうかは、等値判定「==」ではなく、等価判定「equals」を用いて判定する

```Java
String str1 = "aiueo";
String str2 = new String("aiueo");
boolean b = str1.equals(str2);
System.out.println(b); //結果：true
```

#### 5\.indexOf :指定された文字列のインデクスを返す

public int indexOf(String str)

- 引数が1つ場合は、指定された部分文字列が最初に出現する位置のインデクスを返す
- 指定された文字列が見つからない場合は、-1を返す

public int indexOf(String str, int fromIndex)

- 引数が2つの時は、第2引数で指定された検索開始インデクス以降の、指定された部分文字列が最初に出現する位置のインデクスを返す
- 指定された文字列が見つからない場合は、-1を返す

public int indexOf(String str, int beginIndex, int endIndex)

- 引数が3つの時は、第2引数の検索開始位置と第3引数の検索終了位置の範囲内で、指定された部分文字列が最初の出現するインデクスを返す
- 指定された文字列が見つからない場合は、-1を返す
- Java SE 21から導入
- 第2引数が負の場合、または第3引数が文字列の文字数より大きい場合、または第2引数が第3引数より大きい場合は、StringIndexOutOfBoundsExceptionがスローされる

```Java
String str = "aiueoaiueoaiueo";

int i1 = str.indexOf("u");
System.out.println(i1); //結果：2

int i2 = str.indexOf("k");
System.out.println(i2); //結果：-1

int i3 = str.indexOf("u",5);
System.out.println(i3); //結果：7

int i4 = str.indexOf("u",8,14);
System.out.println(i4); //結果：12
```

#### 6\. intern : コンスタントプールの文字列の参照を取得

public String intern()

- コンスタントプールから指定の文字列への参照を取得する。指定の文字列が存在しない場合は、追加してその参照を返す

```Java
String str1 = "aiueo";
String str2 = "aiueo".intern();
System.out.println(str1 == str2); //結果：true
```

#### 7\. length : 文字列の長さを返す

public int length()

- 文字列の長さを返す

```Java
String str = "aiueo";
int i = str.length();
System.out.println(i); //結果：5
```

#### 8\. repeat : 文字列を指定回数繰り返す

public String repeat(int count)

- 文字列を指定回数繰り返した新しい文字列を作成する
- 文字列が空であるか、引数が0の場合は、空の文字列が返される
- 引数が負の場合は、IllegalArgumentExceptionがスローされる

```Java
String str = "あいうえお:".repeat(3);
System.out.println(str); //結果：あいうえお:あいうえお:あいうえお:
```

#### 9\. replace : 指定の文字を指定の文字に置換する

public String replace(char oldChar, char newChar)

- 文字列中にある第1引数の文字を、すべて、第2引数の文字に置換する

public String replace(CharSequence target, CharSequence replacement)

- 文字列中にある第1引数の文字列を、すべて、第2引数の文字列に置換する


```Java
String str1 = "aiueo".replace('a','b');
System.out.println(str1); //結果：biueo

String str2 = "aiueo".replace("a","kak");
System.out.println(str2); //結果：kakiueo

```

#### 10\. substring : 指定された部分文字列を返す

public String substring(int beginIndex)

- 引数が1つの場合は、引数のインデクスから最後までの部分文字列を返す

public String substring(int beginIndex, int endIndex)

- 引数が2つの場合は、第1引数のインデクスから第2引数のインデクス- 1までの部分文字列を返す

```Java
String str1 = "aiueo";
String str2 = str1.substring(1);
System.out.println(str2); //結果：iueo

String str3 = str1.substring(1,4);
System.out.println(str3); //結果：iue
```

#### 11\. toUpperCase : 大文字に変換する

public String toUpperCase()

- 文字列中の文字を全て大文字に変換する

```Java
String str1 = "aiueo";
String str2 = str1.toUpperCase();
System.out.println(str2); //結果：AIUEO
```

#### 12\. toLowerCase : 小文字に変換する

public String  toLowerCase()

- 文字列中の文字を全て小文字に変換する

```Java
String str1 = "AiuEo";
String str2 = str1.toLowerCase();
System.out.println(str2); //結果：aiueo
```

## まとめ

- Stringクラスはイミュータブルである。そのため、String型変数へ値を再代入した場合は、変数の指し示すインスタンスが変化するのではなく、変数の中身が新しいインスタンスへの参照に置き換わる

- イミュータブルの特性を活かして、同じ文字列の参照を自動的に再利用するコンスタントプールという機能がある

---------------

記事は以上です。
最後までお読みいただき、ありがとうございました。

##  参考情報一覧

この記事は以下の情報を参考にして執筆しました。

- [オラクル認定資格教科書 JavaプログラマSilverSE11]
- [徹底攻略 Java SE11 silver 問題集]
- [スッキリわかるJava入門 第４版]
- [パーフェクトJava 改訂3版]
- [16.1 文字列を表すクラスの特徴とAPI（Stringクラス、StringBuilderクラスなど）～Java Basic編](最終更新 2023-11-05)(https://qiita.com/KenyaSaitoh/items/fe85a697abcfe1e11f98) (参照 2025-06-11)
- [JDK SE 21ドキュメント](https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/lang/String.html) (参照 2025-06-11)