Java 関数

Java関数は、Javaプログラミング言語において重要な役割を担っています。この関数によって、開発者は繰り返し呼び出すことができるコードのブロックを定義することができ、コードの再利用や、より組織的で効率的なプログラムの作成が容易になります。

Java main関数

main関数は、あらゆるJavaプログラムにおいて重要な部分です。プログラムが実行されると、Java仮想マシン(JVM)はmain関数内のコードの実行を開始します。main関数は、次のように定義されています。

public static void main(String[] args) {
    // コード
}

main関数は、JVMからアクセス可能でなければならないので、publicとして宣言されなければなりません。また、オブジェクトが生成される前にJVMから呼び出されるため、staticとして宣言されなければなりません。これは、main関数が定義されているクラスの非静的なフィールドやメソッドにアクセスできないことを意味します。

main関数は、引数として文字列の配列を受け取ります。この配列は一般にargsと呼ばれ、プログラムに渡されるコマンドライン引数が格納されます。例えば、以下のようなコマンドでプログラムを実行した場合、

java MyProgram arg1 arg2 arg3

args[0]にはarg1、args[1]にはarg2、args[2]にはarg3が含まれることになります。もし、プログラムに引数が渡されなければ、argsは空の配列になります。

また、main関数は、値を返さないので、voidと宣言する必要があります。ここでは、main関数を使った簡単なプログラムの例を示します。

public class MyProgram {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

このプログラムを実行すると、コンソールに"Hello, World!"という文字列が表示されます。

ここで重要なのは、main関数が定義されているクラスの名前は"MyProgram"である必要はないということです。有効なJavaのクラス名であれば何でもかまいません。しかし、メイン関数の名前自体は常にmainでなければなりません。なぜなら、JVMはプログラムのエントリポイントとして、最初にmain関数を探すからです。

しかし、この中にすべての処理を記述し、プログラムが長くなると全体の見通しが悪くなります。

Java メソッドの定義

Java関数はメソッドとも呼ばれ、以下のように定義します。

void greet() {
    System.out.println("Hello, World!");
}

関数を呼び出すには、関数名の後に括弧をつけます。

greet();

voidキーワードは、その関数が値を返さないことを示します。関数名はgreetで、()内に何もないので引数をとりません。この関数は、コンソールに文字列"Hello, World!"という文字列を表示する1つのステートメントから構成されています。この関数が呼ばれると、このステートメントが実行され、メッセージが表示されます。

関数は、パラメータを受け取ることもできます。パラメータは、関数が呼び出されたときに渡される値です。これらのパラメータによって、関数はより柔軟に、受け取った入力に応じて異なるアクションを実行することができます。

void greet(String name) {
    System.out.println("Hello, " + name + "!");
}

この関数を特定の名前で呼び出すには、引数として文字列の値を渡します。

greet("John"); // "Hello, John!"
greet("Mike"); // "Hello, Mike!"
greet("Steven"); // "Hello, Steven!"

Java関数は、呼び出し元に値を返すこともできます。これを行うには、関数の戻り値の型を指定し、その後に関数名とパラメータを指定します。

int add(int x, int y) {
    return x + y;
}

この関数は2つの整数の和を返します。戻り値を得るには、変数に代入するか、式の中で使用します。

int sum = add(2, 3);  // sumには5が格納される
int result = add(sum, 4);  // resultには9が格納される

Javaでは、値を返すか、何も返さないことを示す"void"キーワードを使用しなければならないことに留意してください。void型の関数から値を返そうとすると、コンパイル時にエラーが発生します。

Java 関数のアクセス修飾子

Javaでは、メソッドにはアクセスレベルなどを指定する修飾子を付けることができます。アクセス修飾子は以下の4種類があります。

  • public: すべてのクラスからアクセスできる
  • protected: 同一パッケージとサブクラスからアクセスできる
  • default(なし): 同じパッケージのクラスからのみアクセスできる
  • private : 同一クラス内からのみアクセスできる
class Greet {
    public static void greet() {
        System.out.println("Hello, Wolrd!");
    }
    private static void privateGreet() {
        System.out.println("Hello, Jupiter!");
    }
    public static void sameClassPrivateGreet() {
        System.out.println("Access to private method");
        privateGreet();
    }
}

class Main{
    public static void main(String[] args){
        // publicにアクセス
        Greet.greet();

        // privateにはクラス外からアクセスできない
        // Greet.privateGreet(); // error

        // 同じクラスからならアクセスできる
        Greet.sameClassPrivateGreet();
    }
}

Java 関数のstatic修飾子

また、変数やメソッドに付与する修飾子として、static修飾子が使われることもあります。staticキーワードが使用されるメソッドをクラスメソッドと呼び、クラスのインスタンスを作成せずにメソッドを実行できるという特徴を持っています。 クラス名.メソッド名で関数を実行するので、本質的には名前空間と同じように動作します。

class MyClass {
    static void greet() {
        System.out.println("Hello, World!");
    }
}

他のクラスからgreet関数を呼び出すには、次のような構文になります。

MyClass.greet();

それでは、他の例をpublic修飾子とstatic修飾子を組み合わせてみましょう。

class Main {
    public static double triangleArea(int width, int height) {
        return width * height / 2;
    }

    public static void main(String[] args){
        System.out.println(triangleArea(5,4)); // 10.0
    }
}

このコードでは、public修飾子を使って、triangleArea関数に、プログラム内の他のどのクラスからもアクセスできるようにしています。つまり、この関数はMainクラスだけでなく、どのクラスからも呼び出せるということになります。

static修飾子は、triangleArea関数をクラスメソッドにするために使用されます。これにより、クラス名を使って関数を呼び出すことができるようになります。

public staticの組み合わせは、特定のオブジェクトの状態に依存しないユーティリティタスクや何らかの計算を行う関数によく使用されます。この場合、triangleArea関数は、引数として与えられた幅と高さに基づいて三角形の面積を計算し、結果をdouble型として返します。

注目すべきは、main関数もpublic staticと表記されていることです。これは、main関数がすべてのJavaプログラムのエントリポイントであり、プログラム実行時にJavaランタイムから呼び出されるようにpublic staticとマークされている必要があるためです。

Java 関数のオーバーロード

Javaでは、メソッドを一意に識別するためにメソッドシグネチャを使用します。これは、メソッド名、引数の数、引数のデータ型の並びから構成されます。戻り値の型、修飾子、スローされる例外のリストはメソッドシグ二チャの一部ではないので、2つのメソッドが異なるかどうかを判断するために使用されることはありません。

public void greet(String name) {
    System.out.println("Hello, " + name + "!");
}

public void greet(int age) {
    System.out.println("You are " + age + " years old.");
}

これら2つのメソッドは、引数の数と引数のデータ型が異なるため、異なるメソッドシグネチャを持ちます。最初のメソッドは1つの文字列の引数を取り、2番目のメソッドは1つの整数の引数を取ります。その結果、これら2つのメソッドは異なるとみなされ、Javaコンパイラはエラーを出しません。

ここで重要なのは、Javaはメソッド名に加えて、メソッドシグネチャを使ってどのメソッドを呼び出すかを決めるということです。つまり、メソッド名が同じでシグネチャが異なる2つのメソッドは、異なるメソッドとみなされるのです。

つまり、引数のデータ型が異なるだけで、同じ機能を提供する同名のメソッドを宣言できます。この機能をオーバーロードと言います。Java APIでも、オーバーロード機能を用いたメソッドはよく使用されており、これまで変数の値をコンソールに出力するときに使用していたSystem.out.println()メソッドも実はオーバーロードを使用して提供されています。

class Main{
    public static void print(int x){
        System.out.println("Arguments: " + x);
    }

    public static void print(int x, int y){
        System.out.println("Arguments: " + x + " and " + y);
    }

    public static void main(String[] args){
        print(1);
        print(3, 5);
    }
}

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート