Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

ポインタとは

ポインタとは、変数や関数などのオブジェクトが、メモリ上のどの位置(番地)存在するのかを指し示す変数です。

C言語(またはC++)では、特にポインタを意識したプログラミングが必要なことが有名で、例えば、引数にオブジェクトを渡す場合、オブジェクトをコピーして渡すというのが基本の動きになり、呼び指し先の関数で引数の値を書き換えても、呼び出し元の変数には影響を与えません。

もし、変数の参照を渡して呼び指し先で引数の値を書き換えたいときは、「&」(アンパサンド)を用いて、変数のメモリ上のアドレスを取得し、ポインタ変数として関数の引数に渡します。

このように C言語は、メモリのアドレスを直接使用して値を参照したり、書き換えたりできるため、よりハードウェアに近い位置で制御が行える反面、誤って不正なメモリのアドレスを参照して予期せぬデータを読み取ったり、アクセス違反によりプログラムが異常終了することがしばしばありました。

Java にポインタはある?

Java にはポインタ変数のような、メモリのアドレスを直接指定してデータにアクセスする機能はありません。これには、ポインタ変数は、それ自体が複雑で使用が難しく、ソースコードが複雑化してしまうことや、不正なメモリ領域にアクセスしないための安全性などの理由があります。

ただし、ポインタという概念が無くったわかではありません。

Java では、参照型の変数は暗黙的にオブジェクトへのポインタ変数として扱い、intlong などの基本型(プリミティブ型)は、値そのものを変数にもつルールがあります。ルール化することにより、C 言語などのようなポインタ変数の複雑性をなくし、プログラムを読みやすくしており、Java 以外の C# などのプログラム言語でも同じようなアプローチがとられています。

値渡し

値渡しとは、変数の値を自体をメソッドの引数などに渡すことを言います。基本型(プリミティブ型)の変数を引数に渡すときは、すべてのこの値渡しになります。

実際に値渡しのサンプルコードを見てみましょう。

次のサンプルコードは、main メソッドの中で定義した 変数 value を、別の add メソッドに引数として渡して、add メソッドの中で引数の値に 10 を加算する例です。

public class Main {
    // 最初に呼ばれるメインメソッド
    public static void main(String[] args){
        int value = 10;
        add(value);
        System.out.println("value=" + value);
    }

    // 引数の値に10を足すメソッド
    public static void add(int value) {
        value = value + 10;
    }
}

上のコードを実行すると、次の結果になります。

value=10

変数 value の値を add メソッドの中で加算していましたが、main メソッドの中で定義した value の値には変更がありません。

これは、値渡しの場合、単純に変数の値のコピーを引数に渡しているため、呼び出し先のメソッドで変数の値をいくら変更しても、呼び出し元の変数には影響を与えないためです。

値渡しの対象となるデータ型

基本型(プリミティブ型)の変数はすべて値渡しの対象になります。

Java の基本型(プリミティブ型)は、次の8種類です。

【関連記事】
【Java】データ型に関する基礎知識 基本型と参照型を把握しよう

参照渡し(ポインタ渡し)

冒頭でも述べたように、Java では ArrayList クラスなどをはじめとる、基本型(プリミティブ型)以外の参照型の変数を引数に渡すときは、参照渡しとなります。

これは、参照型の変数には、対象のオブジェクトが格納されているポインタ(メモリ上のアドレス)が格納されていることにより、呼び出し先のメソッドでも同じメモリ上のアドレスを参照する変数となり、結果的に、呼び出し元の変数が参照できているかのような動きになります。

ポテパンダの一言メモ

一部のサイトや書籍では、参照型の変数を引数で渡すときは、変数への参照が呼び出し先のメソッドに渡されなどと書かれている場合がありますが、厳密にはこれは誤りです。

Java では、メソッドの引数に変数を指定する場合、基本型(プリミティブ型)や参照型に関わらず、変数の中身をコピーした値を引数に渡します。これが、基本型(プリミティブ型)の時は、変数には値そのものが格納されているため値がコピーされ、参照型の時はポインタが格納されているという違いがあるだけです。

実際に、参照型の変数を引数に渡す例を見てみましょう。

次のコードは、String の配列をメソッドの引数に渡し、呼び出し先のメソッドで配列の一部の要素の値を書き換える例です。配列の変数は参照型となるため、以下の例は参照渡し(ポインタ渡し)となります。

public class Main {
    // 最初に呼ばれるメインメソッド
    public static void main(String[] args){
        String[] array = {"Java", "Python", "Ruby"};
        change(array);

        for (String str : array) {
            System.out.println(str);
        }
    }

    // 配列を引数で受け取り、2つ目の要素の値を書き換えるメソッド
    public static void change(String[] array) {
        array[1] = "C++";
    }
}

実行結果は次のとおりです。配列の2つ目の要素が、change メソッドの中で書き換えられた値に変わっていることが分かります。

Java
C++
Ruby

基本型(プリミティブ型)でも参照渡しをしたい

基本型(プリミティブ型)でも参照渡しにすることで、別のメソッドの中で変数の値を書き換えたいと思う方もいるでしょうが、Java では 基本型(プリミティブ型)は値のコピーしか引数に渡すことができないため、参照渡しにしたい場合は、次のように配列型にしてポインタを渡すなどの対応が必要です。

public static void main(String[] args){
  // 参照渡したい int の変数をいったん配列に入れる
  int a = 10;
  int[] ary = {a};

  // 配列を引数で渡し、メソッドの中で値を書き換える
  change(ary);

  // 配列の中から変更された値を取り出す
  a = ary[0];

  System.out.println("a=" + a);        // a=100
}

public static void change(int[] array) {
  array[0] = 100;
}

Stringは値渡し?

Java では、文字列を格納する String も参照型です。つまり、String 型の変数をメソッドの引数にしていすると、その変数のポインタが渡る参照渡しとなります。

一部では、String 型だけは特殊な扱いで、参照型でも値渡しになると勘違いされる方もいますが、String 型も他の参照型と同様に引数にポインタが渡る参照渡しです。

ただし、String 型は、 immutable な(状態を変えられない)オブジェクトであるため、呼び出し先のメソッドで値を書き換えることが出来ません。(逆にこの性質が String 型は値私になるという誤解を生んでいるようです)

【関連記事】
【Java】 メソッドを徹底解説!定義から呼び出し、戻り値、引数まとめ

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。