java 변경 - 비 정적 변수는 정적 컨텍스트에서 참조 할 수 없습니다.




사용 차이 (13)

static 키워드는 클래스 내의 메소드 또는 변수의 라이프 사이클을 수정합니다. static 메서드 또는 변수는 클래스가로드 될 때 만들어집니다. static 으로 선언되지 않은 메서드 나 변수는 클래스가 new 연산자를 사용하여 객체로 인스턴스화 될 때만 만들어집니다.

넓은 의미에서 클래스의 라이프 사이클은 다음과 같습니다.

  1. 클래스의 소스 코드는 템플릿이나 패턴 또는 스탬프를 작성하여 작성한 다음 사용할 수 있습니다.
  2. 클래스를 사용하여 new 연산자를 사용하여 클래스의 인스턴스를 실제 객체로 만든 다음 객체로 완료 할 때 객체를 만듭니다.
  3. 쓰레기 수거 중에 메모리와 같이 보유하고있는 자원을 회수하는 객체를 파괴하십시오.

응용 프로그램의 초기 진입 점을 갖기 위해 Java는 Java 프로그램이 합의되거나 특별한 이름을 가진 메소드를 포함하는 클래스를 가져야한다는 규칙을 채택했습니다. 이 특별한 방법을 main() 이라고합니다. main 메소드를 포함하는 클래스가 인스턴스화되었는지 여부에 관계없이 메소드가 존재해야하므로 main() 메소드를 static 수정 자로 선언해야 클래스가로드 되 자마자 main() 메소드를 사용할 수 있습니다.

결과적으로 java helloworld 와 같은 명령 줄을 사용하여 Java 응용 프로그램을 시작하면 일련의 작업이 수행됩니다. 우선 Java 가상 머신이 시작되고 초기화됩니다. 컴파일 된 Java 코드가 들어있는 helloworld.class 파일이 Java 가상 머신에로드됩니다. 그런 다음 Java 가상 시스템은 main(String [] args) 이라는 helloworld 클래스에서 메소드를 찾습니다. 이 메소드는 클래스가 실제로 객체로 인스턴스화되지 않은 경우에도 존재하도록 static 이어야합니다. 자바 가상 머신은 클래스로부터 객체를 생성하여 클래스의 인스턴스를 생성하지 않습니다. 그냥 클래스를로드하고 main() 메소드에서 실행을 시작합니다.

따라서 클래스의 인스턴스를 객체로 만들어야하며 static 수정 자로 선언되지 않은 클래스의 메서드와 변수에 액세스 할 수 있습니다. Java 프로그램이 main() 함수로 시작되면로드되는 클래스의 일부로 존재하기 때문에 static 의 수정자를 갖는 모든 변수 또는 메소드를 사용할 수 있습니다.

그러나 static 수정자를 가지지 않는 main() 메서드 외부에있는 클래스의 변수 및 메서드는 클래스의 인스턴스가 main() 메서드 내에서 객체로 만들어 질 때까지 사용할 수 없습니다. 객체를 만든 후에는 객체의 변수와 메서드를 사용할 수 있습니다. 클래스의 객체를 거치지 않고 static 수정자를 가지지 않는 클래스의 변수와 메소드를 사용하려는 시도는 컴파일시 자바 컴파일러에 의해 잡히고 오류로 표시됩니다.

import java.io.*;

class helloworld {
    int myInt;      // this is a class variable that is unique to each object
    static int myInt2;  // this is a class variable shared by all objects of this class

    static void main (String [] args) {
        // this is the main entry point for this Java application
        System.out.println ("Hello, World\n");
        myInt2 = 14;    // able to access the static int
        helloworld myWorld = new helloworld();
        myWorld.myInt = 32;   // able to access non-static through an object
    }
}

나는이 테스트 코드를 작성했다.

class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}

그러나 다음과 같은 오류가 발생합니다.

Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^

내 클래스 변수를 인식 할 수있는 방법을 얻으려면 어떻게해야합니까?


정적 메서드에서 액세스하려면 정적 멤버 변수가 필요합니다.

public class MyProgram7 {
  static Scanner scan = new Scanner(System.in);
  static int compareCount = 0;
  static int low = 0;
  static int high = 0;
  static int mid = 0;  
  static int key = 0;  
  static Scanner temp;  
  static int[]list;  
  static String menu, outputString;  
  static int option = 1;  
  static boolean found = false;

  public static void main (String[]args) throws IOException {
  ...

나는 당신에게 정적 인 것을 설명하려고 노력할 것이다. 우선 모든 정적 변수는 클래스의 특정 인스턴스에 속하지 않습니다. 그들은 수업의 이름으로 인정받습니다. 정적 메소드는 다시 특정 인스턴스에 속하지 않습니다. 그들은 정적 변수에만 액세스 할 수 있습니다. MyClass.myMethod ()를 호출하고 myMethod를 정적 메서드라고 가정 해 보겠습니다. 메소드 내에서 비 ​​정적 변수를 사용한다면, 어떻게하면 어떤 변수를 사용할 지 알 수 있을까요? 그래서 정적 메소드에서만 정적 변수를 사용할 수 있습니다. 나는 그들이 어떤 특별한 경우에도 속하지 않는다는 것을 다시 반복한다.


먼저 프로그램을 분석해 봅시다. 프로그램에서 첫 번째 메서드는 main() 입니다. 정적 메서드라는 것을 명심하십시오. 그런 다음 해당 메서드의 로컬 변수를 선언합니다 (compareCount, low, high 등). ). 이 변수의 범위는 정적 또는 비 정적 메서드가 아니더라도 선언 된 메서드뿐입니다. 그래서 당신은 그 방법 밖에서 그 변수들을 사용할 수 없습니다. 이것이 기본 오류입니다.

그런 다음 다음 지점으로갑니다. 넌 정적이 너를 죽이고 있다고했다. (그것은 당신을 죽일지도 모르지만 그것은 당신의 프로그램에만 생명을 부여합니다 !!) 우선 기본적인 것을 이해해야합니다. * 정적 메서드는 정적 메서드 만 호출하고 정적 변수 만 사용합니다. * 정적 변수 또는 정적 메소드는 해당 클래스의 인스턴스에 종속되지 않습니다. (즉, 정적 변수의 상태를 변경하면 클래스의 모든 객체에 반영됩니다.) *이 때문에 클래스 변수 또는 클래스 메소드로 호출합니다. 그리고 "정적 인"키워드에 관해 더 많은 것이 있습니다. 나는 당신이 아이디어를 얻길 바랍니다. 먼저 변수의 범위를 변경하고 정적 메소드로 선언하십시오 (정적 메소드에서 사용할 수 있음).

그리고 당신에게 조언은 : 당신은 변수와 정적 기능의 범위에 대한 아이디어를 잘못 이해했습니다. 그것에 대해 명확한 아이디어를 얻으십시오.


이것은 모든 초보자를위한 정적 키워드에 대해 설명하기에 조금 다릅니다.
클래스와 객체로 더 많은 작업을 할 때 명확하게 알게됩니다.

| * | 정적 : 클래스 이름으로 정적 항목을 호출 할 수 있습니다.
코드에서 관찰 할 경우 일부 함수는 클래스 이름과 같이 직접 호출됩니다.

NamCls.NamFnc();

System.out.println();

이것은 NamFnc와 println이 키워드 앞에 static을 사용하여 선언되기 때문입니다.

| * | 비 정적 : 클래스 변수로 비 정적 항목을 호출 할 수 있습니다.
정적이 아니라면 클래스의 변수가 필요합니다.
클래스 변수 뒤에 점을 넣고
그런 다음 함수를 호출하십시오.

NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();

아래 코드는 당신을 깔끔하게 설명합니다.

| * | 클래스 내의 정적 및 비 정적 함수 :

public class NamCls
{
    public static void main(String[] args)
    {
        PlsPrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamObjVar.PrnFnc("Tst Txt");
    }

    static void PlsPrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }

    void PrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }
}

| * | 클래스 내부의 정적 및 비 정적 클래스 :

public class NamCls
{
    public static void main(String[] args)
    {
        NamTicCls NamTicVaj = new NamTicCls();
        NamTicVaj.PrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamNicCls NamNicVar = NamObjVar.new NamNicCls();
        NamNicVar.PrnFnc("Tst Txt");
    }

    static class NamTicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }

    class NamNicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }
}

이 시도..

public class StaticTest {

    private int count=0;
    public static void main(String args[]) throws IOException {
        StaticTest test = new StaticTest(); //accessing static variable by creating an instance of class
        System.out.println(test.count);
    }       
}

내가 너를 도울 수 있기를 바란다 ..!


정적 필드와 메소드는 인스턴스가 아닌 클래스 자체에 연결됩니다. 클래스 A , 'normal'메서드 b 및 정적 메서드 c 가 있고 클래스 A 의 인스턴스를 만들 경우 Ac()ab() 대한 호출이 유효합니다. 방법 c() 는 어떤 인스턴스가 연결되어 있는지 모르기 때문에 비 정적 필드를 사용할 수 없습니다.

해결 방법은 필드를 정적으로 만들거나 메서드를 비 정적으로 만드는 것입니다. 당신은 메인이 다음과 같이 보일 수 있습니다 :

class Programm {
  public static void main(String[] args){
    Programm programm = new Programm();
    programm.start();
  }
  public void start(){
    // can now access non-static fields
  }
}

인스턴스 메소드 또는 인스턴스 변수를 호출하기 전에 객체 (인스턴스)가 필요합니다. 인스턴스 변수가 정적 메소드에서 호출 될 때 컴파일러는이 변수가 어느 객체에 속해 있는지 알지 못합니다. 정적 메서드에는 객체가 없으므로 (단 하나의 복사본 만 항상). 인스턴스 메소드에서 인스턴스 변수 또는 인스턴스 메소드를 호출하면이 메소드 this 객체를 참조합니다. 즉, 변수가 생성 된 객체에 속하며 각 객체에는 인스턴스 메서드 및 변수의 자체 복사본이 있습니다.

정적 변수는 정적으로 표시되고 인스턴스 변수에는 특정 키워드가 없습니다.


클래스와 해당 클래스의 인스턴스 사이의 차이를 이해해야합니다. 거리에서 자동차를 본다면 모델이나 유형을 볼 수없는 경우에도 자동차임을 즉각 알 수 있습니다. 이것은 여러분이 보는 것을 "car" 클래스 와 비교하기 때문입니다. 이 클래스에는 모든 자동차와 비슷한 내용이 포함되어 있습니다. 그것을 템플릿 또는 아이디어로 생각하십시오.

동시에, 당신이 본 차는 클래스 "차"의 인스턴스입니다. 왜냐하면 그것은 당신이 기대하는 모든 속성을 가지고 있기 때문입니다 : 운전하는 사람이 있고, 엔진과 바퀴가 있습니다.

그래서 클래스는 "모든 차량에 색이 있습니다."인스턴스에 "이 특정 차량은 빨간색"이라고 표시됩니다.

객체 지향 세계에서는 클래스를 정의하고 클래스 내부에서 Color 유형의 필드를 정의합니다. 클래스가 인스턴스화 될 때 (특정 인스턴스를 만들 때) 메모리는 해당 색상에 대해 예약되어 있으므로이 특정 인스턴스에 색상을 지정할 수 있습니다. 이러한 특성은 구체적이므로 비 정적입니다.

정적 필드와 메소드는 모든 인스턴스와 공유됩니다. 그들은 특정 인스턴스가 아닌 클래스에 특정한 값을위한 것입니다. 메소드의 경우 일반적으로 전역 도우미 메소드 (예 : Integer.parseInt() )입니다. 필드의 경우 일반적으로 상수입니다 (예 : 자동차 유형, 즉 자주 변경되지 않는 제한된 세트가있는 곳).

문제를 해결하려면 런타임에서 인스턴스의 메모리를 예약 할 수 있도록 클래스의 인스턴스 (인스턴스 생성)를 생성해야합니다. 그렇지 않으면 다른 인스턴스가 원하지 않는 다른 인스턴스를 덮어 씁니다.

귀하의 경우 다음 코드를 시작 블록으로 사용해보십시오.

public static void main (String[] args)
{
    try
    {
        MyProgram7 obj = new MyProgram7 ();
        obj.run (args);
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
}

// instance variables here

public void run (String[] args) throws Exception
{
    // put your code here
}

main() 메서드는 인스턴스에 포함 된 클래스의 인스턴스를 만듭니다 (이상하게 들리지만 인스턴스 대신 클래스로 main() 이 만들어지기 때문에이 작업을 수행 할 수 있음) 인스턴스 메서드 ( run() )를 호출합니다.


아주 기본적인 것은 정적 변수이거나 정적 메서드는 클래스 수준에 있습니다. 클래스 수준의 변수 또는 메서드는 인스턴스 수준의 메서드 나 변수보다 먼저로드됩니다. 물론로드되지 않은 것은 사용할 수 없습니다. 그래서 자바 컴파일러는 컴파일 타임에 런타임에 처리되는 것을 처리하지 않도록한다. 그것이 정적 컨텍스트에서 비 정적 인 것들을 참조 할 수없는 에러를주는 이유입니다. 클래스 수준 범위, 인스턴스 수준 범위 및 로컬 범위에 대해서 읽는 것만으로도 충분합니다.


class MyProgram
{
  int count = 0; // non-static variable / instance variable
  public static void main (String[] args) // static method
  {
    MyProgram c = new MyProgram(); // create c as reference variable
    System.out.println(c.count); // call non-static variable using a reference variable name (c)
  }
}

컴파일러는 "당신이 말하는 객체의 intance 변수를 모르겠습니다"라고 생각합니다.

자바 온라인

body, html, iframe { 
  width: 100% ;
  height: 100% ;
  overflow: hidden ;
}
<iframe src="https://ideone.com/SIDcv1" ></iframe>


  • 첫 번째로 클래스의 인스턴스와 클래스 자체의 차이점을 알아야합니다. 클래스는 특정 속성과 해당 속성의 컨텍스트에서 전체의 동작을 모델링합니다. 인스턴스는 해당 속성에 대한 특정 값을 정의합니다.

  • static 키워드에 바인드 된 것은 클래스의 인스턴스 컨텍스트가 아닌 클래스의 컨텍스트에서 사용할 수 있습니다.

  • 위의 결과로

    1. 메소드 내의 변수는 정적 일 수 없습니다.
    2. 정적 필드 및 메소드는 class-name 예 : MyProgram7.main (...)을 사용하여 호출해야합니다.
  • 정적 필드 / 메소드의 수명은 애플리케이션의 수명과 같습니다.

예를 들어, 자동차는 속성 색을 가지며 '동작'동작을 나타냅니다. 자동차의 경우는 25kmph에서 동작하는 빨간색 폭스 바겐 딱정벌레입니다.

이제 자동차의 정적 속성은 도로의 바퀴 수 (4)가되며 모든 자동차에 적용됩니다.

HTH


Java의 비 정적 중첩 클래스에는 상위 클래스의 인스턴스 에 대한 암시 적 참조가 포함됩니다. 따라서 Node 를 인스턴스화하려면 Stack 인스턴스도 필요합니다. 정적 컨텍스트 (기본 메서드)에는 참조 할 Stack 인스턴스가 없습니다. 따라서 컴파일러는 Node 생성 할 수 없음을 나타냅니다.

Node 를 정적 클래스 (또는 정규 외부 클래스)로 만들면 Stack 대한 참조가 필요하지 않으며 정적 기본 메서드에서 직접 인스턴스화 할 수 있습니다.

Example 8.1.3-2와 같은 자세한 내용은 Java 언어 사양, 8 장 을 참조하십시오.





java variables compiler-errors non-static