

以下のプログラムで２点質問がございます。

  1. メインクラス内で`ST_Test.testMethod(2);`を書くと、メソッドが実行されるのですが、staticクラスであるST_Testクラスで、`ST_Test.testMethod(2);`を書くと、コンパイルエラーがでます。  
エラー内容は以下の通りです。これはなぜ起こるのでしょうか？メインクラスで書くのと、staticクラス内で書くのとでは大きな違いでもあるのでしょうか？

[code]     estmain.java:45: エラー: <identifier>がありません

        ST_Test.testMethod(2);
                          ^
    testmain.java:45: エラー: 型の開始が不正です
        ST_Test.testMethod(2);
                           ^
    エラー2個
    
[/code]

  2. 今回、ST_Testクラスはメインクラスでないため、
[code]     static class ST_Test

    
[/code]

と書きましたが、staticを敢えて書かずに、「class ST_Test」とだけ描いても問題ないでしょうか？

[code]     //インスタンスメソッドとstaticメソッドの違いを理解するプログラム

    public class Testmain {
    
        public static void main(String[] args) {
            ST_Test.testMethod(2);
        }
    
        static class ST_Test{
    
            public static String S_STR = "S_STR";
            public String str = "str";int n;
    
            ST_Test.testMethod(2);
    
            public static void testMethod(int i) {
                System.out.println("i="+i);
            }
        }
    }
    
[/code]

**実行環境**

  * openjdk version "1.8.0_242"
  * OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_242-b08)
  * OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.242-b08, mixed mode)


CC BY-SA 4.0
2020-08-23T10:11:33.813
69801
2020-08-28T01:24:02.690
2020-08-28T01:24:02.690
3060
39688
question
java
static クラス内でクラス.クラスメソッド名を実行したところ、エラーが出ます。理由がわかりません。


# コンパイルエラーの理由

Javaのクラスの中にメソッド呼び出しをいきなり書くことはできません。

[code]

    static class ST_Test{
        public static String S_STR = "S_STR"; // ここはプロパティなのでOK
        public String str = "str";int n;      // ここもプロパティなのでOK
    
        ST_Test.testMethod(2);  // ここにメソッド呼び出しはNG
    }
    
[/code]

できないことをやろうとなさっているので、何がしたいのか不明ではありますが、コンパイルを通すように修正してみたものが下記です。

[code]

    public class Testmain {
        public static void main(String[] args) {
            ST_Test.testMethod(2);
            ST_Test.hoge();
        }
    
        static class ST_Test{
            public static String S_STR = "S_STR";
            public String str = "str";int n;
    
            public static void hoge() {
                ST_Test.testMethod(1); // 直接書けないのでhogeメソッドで包む。引数ももう一つの呼び出しと区別しやすいように 2から1へ変更
            }
    
            public static void testMethod(int i) {
                System.out.println("i="+i);
            }
        }
    }
    
[/code]

> メインクラス内でST_Test.testMethod(2);を書くと、メソッドが実行される

と表現されていますが、厳密には
`Testmain`内の`mainメソッド`内で`ST_Test.testMethod(2);`を書いていますので、クラスの中にいきなりメソッド呼び出しをしているわけではありません。

> メインクラスで書くのと、staticクラス内で書くのとでは大きな違いでもあるのでしょうか？

よって、違いは、メソッドの中でメソッド呼び出しをしていたか、そうでないかです。`static`クラスであるかそうでないかは関係ありません。

# クラスにstaticは必要かどうか

> staticを敢えて書かずに、「class ST_Test」とだけ描いても問題ないでしょうか？

コンパイルが通るようになったので、`static class ST_Test`から`static`を削除してみるとどうなるか確認してみます。

そうすると下記のようなエラーが出ました。

[code]

    Testmain.java:8: error: Illegal static declaration in inner class Testmain.ST_Test
            public static String S_STR = "S_STR";
                                 ^
      modifier 'static' is only allowed in constant variable declarations
    Testmain.java:11: error: Illegal static declaration in inner class Testmain.ST_Test
            public static void hoge() {
                               ^
      modifier 'static' is only allowed in constant variable declarations
    Testmain.java:15: error: Illegal static declaration in inner class Testmain.ST_Test
            public static void testMethod(int i) {
                               ^
      modifier 'static' is only allowed in constant variable declarations
    
[/code]

ですので、`static` は必要なようです。


CC BY-SA 4.0
2020-08-23T13:50:00.967
69807
2020-08-23T14:03:02.907
2020-08-23T14:03:02.907
9008
9008
69801
answer


質問2についてですが、staticは必要です。このプログラムはTestmainクラスのオブジェクトを生成しない状態で動いているので、Testmainクラスがインスタンシエイトされてからでないと使えないnon-
staticなinner classをこの流れで呼び出すことはできません。

全体をnon-staticで書くのであれば例えば以下のようになります。

[code]

    public class Testmain {
        public static void main(String[] args) {
            Testmain main = new Testmain();
            ST_Test st_test = main.new ST_Test();
            st_test.testmethod(2);
        }
    
        private class ST_Test {
            public void testmethod(int i) {
                System.out.println("i="+i);
            }
        }
    }
    
[/code]

お題が「インスタンスメソッドとstaticメソッドの違いを理解するプログラム」ということなので、納得されるまでいろいろコードをいじって掴むようにするのが良いと思います。最初のころは（人によっては）全部staticなプログラムを書いてしまいがちなのですが、あまり良い習慣ではないのでクラスとインスタンスの関係を把握しながらコードを書く癖をつけた方が良いです。


CC BY-SA 4.0
2020-08-28T01:20:19.950
69928
2020-08-28T01:20:19.950
5734
69801
answer