【Java】staticメソッドと非staticメソッドの違いとよくあるエラーの解決方法

## はじめに
Javaの学習を始めたばかりの方は、`static`と付けるメソッドと付けないメソッドの違いに戸惑うことが多いかと思います。特に、間違った使い方をすると、次のようなエラーメッセージが表示されます。

```
non-static method cannot be referenced from a static context
```

この記事では、`static`メソッドと非`static`メソッドの違いと、使い方の基本を整理します。
また、初心者が躓きやすいポイントについても紹介します。


## 1. staticメソッドとは？
### 1. 特徴

- クラス単位で呼び出すことができるメソッド。
- インスタンスの生成は不要で、クラス名だけで呼び出すことができる。
- 状態（インスタンスごとのデータ）を持たない処理に使う。

### 2.staticメソッドの例
以下のコードは、足し算を行う`static`メソッドを使っています。

```java        
public class Main {
    public static void main(String[] args) {
        System.out.println(Calculator.add(3, 5)); // 8
    }
}

class Calculator {
    public static int add(int a, int b) { // staticメソッド
        return a + b;
    }
}
```
```
n-okutomi@middlewares % java Main      
8
```
#### 解説：
- `add`メソッドは`static`が付いているので、クラス名（Calculator） から直接呼び出すことができます。
- `add`メソッドは入力（aとb）だけで計算をしているので、何かを記憶していません。
毎回「足し算だけをする」処理（状態を持たない処理）です。

## 3. 非staticメソッドとは？
### 1. 特徴
- インスタンスごとに動作するメソッド。
- インスタンスを生成してから呼び出す必要がある。
- インスタンスごとの状態（データ）を保持し、変更する処理に使う。


### 2. 非staticメソッドの例
以下のコードは、カウンターの状態（数値）を保持し、増加させる処理です。

```java        
public class Main {
    public static void main(String[] args) {
        Counter c1 = new Counter(); // インスタンス生成
        c1.increment();
        c1.printCount(); // カウント: 1

        Counter c2 = new Counter(); // 別のインスタンス
        c2.printCount(); // カウント: 0
    }
}

class Counter {
    private int count = 0; // 状態を保持する変数

    public void increment() { // 非staticメソッド
        count++;
    }

    public void printCount() { // 非staticメソッド
        System.out.println("カウント: " + count);
    }
}
```
```
n-okutomi@middlewares % java Main      
カウント: 1
カウント: 0
```
#### 解説：
- `increment`と`printCount`は非`static`メソッドなので、インスタンス（`c1`, `c2`）が必要です。
- インスタンスごとに`count`という状態が保持されるため、`c1`と`c2`の値は異なります。

## 4. 初心者がつまずくエラーと解決方法
#### 間違ったコード例
次のコードは、`static`メソッド内から非`static`メソッドを直接呼び出そうとしています。

```java        
class Mistake {
    public void showMessage() { // 非staticメソッド
        System.out.println("非staticメソッド");
    }

    public static void main(String[] args) {
        showMessage(); // エラー発生！
    }
}

```
#### エラーメッセージ
```      
Main.java:7: エラー: staticでないメソッド showMessage()をstaticコンテキストから参照することはできません
        showMessage(); // エラー発生！
        ^
エラー1個
```
#### 原因
- `main`メソッドは`static`なので、インスタンスが存在しない状態で動作しています。
- 非`static`メソッドはインスタンスが必要なので、直接呼び出せません。

#### 正しい書き方
非`static`メソッドを使うためには、インスタンスを生成してから呼び出します。

```java
public class Mistake {
    public void showMessage() {
        System.out.println("非staticメソッド");
    }

    public static void main(String[] args) {
        Mistake mistake = new Mistake(); // インスタンス生成
        mistake.showMessage(); // 正しく呼び出せる
    }
}

```
```
n-okutomi@middlewares % java Mistake.java       
非staticメソッド
```

## 5. staticメソッドと非staticメソッドの使い分け
| 項目 | staticメソッド | 非staticメソッド |
|-----------|------------|------------|
| 呼び出し方   | クラス名で呼び出す  | インスタンスを通して呼び出す |
| 状態（データ）     | 持たない      | インスタンスごとに保持する       |
| 使う場面       | 共通の処理        | オブジェクトごとの処理         |
	
#### ポイント：
- staticメソッド：
　状態を持たず、固定された処理を行う場合（例: 計算処理、ユーティリティクラス）。
- 非staticメソッド：
　オブジェクトごとに異なるデータや状態を扱う場合。

## 6. おわりに
今回は、Javaの`static`メソッドと非`static`メソッドの違いについて紹介しました。
まとめは以下の通りです。

- staticメソッドは、インスタンスを生成せずに使えるクラス単位のメソッドです。
- 非staticメソッドは、インスタンスごとに状態を持つメソッドです。
- staticのついたメソッドから非staticメソッドを呼び出すには、インスタンスの生成が必要です。

この記事を通して、`static`メソッドと非`static`メソッドの基本を学ぶきっかけになれば幸いです。