[java] ‘정적’키워드는 클래스에서 무엇을합니까?

구체적으로, 나는이 코드를 시도했다 :

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

그러나 그것은 오류를 주었다

정적 메소드 main에서 비 정적 필드에 액세스 할 수 없음

그래서 나는 clock이것으로 선언을 바꿨다 .

static Clock clock = new Clock();

그리고 효과가있었습니다. 해당 키워드를 선언 전에 두는 것은 무엇을 의미합니까? 해당 객체에 수행 할 수있는 작업과 관련하여 정확히 무엇을하고 /하거나 제한합니까?



답변

static 멤버는 특정 인스턴스 대신 클래스에 속합니다.

이는 클래스의 인스턴스를 백만 개 만들거나 만들지 않은 경우에도 하나의 static필드 인스턴스 만 존재 한다는 것을 의미 합니다 [1] . 모든 인스턴스가 공유합니다.

static메소드는 특정 인스턴스에 속하지 않기 때문에 인스턴스 멤버를 참조 할 수 없습니다. 주어진 예에서, main어떤 Hello클래스의 인스턴스 (따라서 Clock클래스의 인스턴스 )를 참조해야하는지 알 수 없습니다. static회원은 회원 만 참조 할 수 있습니다 static. 인스턴스 멤버는 물론 static멤버에 액세스 할 수 있습니다 .

참고 : 물론 static멤버 는 객체 참조를 통해 인스턴스 멤버에 액세스 할 수 있습니다 .

예:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1] : 런타임 특성에 따라 ClassLoader 또는 AppDomain 또는 스레드 당 하나 일 수 있지만 그 점이 아닙니다.


답변

“Hello”클래스의 개별 인스턴스마다 하나씩이 아니라 Hello에 “clock”인스턴스가 하나만 있다는 의미입니다. 따라서 모든 인스턴스간에 공통적으로 공유되는 “clock”참조가 하나 있음을 의미합니다. “Hello”클래스

따라서 코드의 어느 곳에서나 “새 Hello”를 수행해야하는 경우 : 첫 번째 시나리오 ( “정적”을 사용하지 않고 변경 전)에서 “새 Hello”를 호출 할 때마다 새 시계가 만들어집니다. 그러나 두 번째 시나리오 ( “정적”을 사용한 변경 후)의 B-에서는 모든 “새 Hello”인스턴스가 여전히 처음 작성된 초기 및 동일한 “시계”참조를 공유하고 사용합니다.

메인 외부의 “시계”가 필요하지 않으면 다음과 같이 작동합니다.

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();
    }
}


답변

static키워드 수단은 무엇인가 (필드, 방법 또는 중첩 클래스)하는 관계가 형식 이 아닌 특정 인스턴스의 유형. 예를 들어, 클래스의 Math.sin(...)인스턴스없이 호출 하면 Math클래스 의 인스턴스를 만들 수 없습니다Math .

자세한 정보는 관련 Oracle Java Tutorial 비트를 참조하십시오 .


사이드 노트

Java는 불행히도 정적 멤버가 인스턴스 멤버 인 것처럼 액세스 할 수 있습니다. 예 :

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

즉, 만들어 보는 것처럼 sleep인스턴스 방법이지만, 실제로는 정적 방법입니다 – 그것은 항상 현재의 thread의 잠을 수 있습니다. 호출 코드에서이를 명확하게하는 것이 좋습니다.

// Clearer
Thread.sleep(5000);


답변

staticJava 의 키워드는 변수 또는 함수가 실제 객체 자체가 아니라 유형에 속하는 해당 클래스의 모든 인스턴스간에 공유됨을 의미합니다 .

따라서 변수가 있고 한 인스턴스에서 변수 private static int i = 0;를 늘리면 ( i++) 모든 변경 사항이 모든 인스턴스에 반영됩니다. i이제 모든 인스턴스에서 1이됩니다.

정적 메소드는 객체를 인스턴스화하지 않고 사용할 수 있습니다.


답변

정적 멤버의 기본 사용법 …

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}

이렇게하면 클래스 인스턴스 Hello를 다른 클래스로 보내지 않고 모든 클래스 멤버에서 값을 공유 할 수 있습니다. 정적 클래스는 클래스 인스턴스를 만들 필요가 없습니다.

Hello hello = new Hello();
hello.staticValue = "abc";

클래스 이름으로 정적 값이나 메소드를 호출 할 수 있습니다.

Hello.staticValue = "abc";


답변

정적은 클래스와 연결된 메서드 나 변수를 사용하기 위해 클래스의 인스턴스를 만들 필요가 없음을 의미합니다. 귀하의 예에서 다음을 호출 할 수 있습니다.

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

직접 대신 :

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

정적 메서드 (클래스에 속함) 내에서는 정적이 아닌 멤버에 액세스 할 수 없습니다. 값은 클래스의 인스턴스화에 따라 달라지기 때문입니다. 인스턴스 멤버 인 비 정적 Clock 객체는 Hello 클래스의 각 인스턴스에 대해 다른 값 / 참조를 가지므로 클래스의 정적 부분에서 액세스 할 수 없습니다.


답변

자바 정적 :

정적은 비 액세스 수정 자입니다. 정적 키워드는 클래스의 인스턴스보다 클래스에 속합니다. 변수 또는 메소드를 클래스에 첨부하는 데 사용할 수 있습니다.

정적 키워드는 다음과 함께 사용할 수 있습니다.

방법

변하기 쉬운

다른 클래스 내에 중첩 된 클래스

초기화 블록

다음과 함께 사용할 수 없습니다 :

클래스 (중첩되지 않음)

건설자

인터페이스

메서드 로컬 내부 클래스 (차이와 중첩 클래스)

내부 클래스 메소드

인스턴스 변수

지역 변수

예:

생성자에서 증가한 count라는 인스턴스 변수 가있는 다음 예제를 상상해보십시오 .

package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

산출:

1 1 1

인스턴스 변수는 객체 생성시 메모리를 가져 오므로 각 객체는 인스턴스 변수의 복사본을 갖게되며, 증가하면 다른 객체에는 반영되지 않습니다.

이제 인스턴스 변수 수를 정적 변수 수로 변경 하면 프로그램에서 다른 출력을 생성합니다.

package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

산출:

1 2 3

이 경우 정적 변수는 메모리를 한 번만 가져옵니다. 객체가 정적 변수의 값을 변경하면 해당 값을 유지합니다.

최종 정적 :

final 및 static으로 선언 된 전역 변수 는 전체 실행에서 변경되지 않은 상태로 유지됩니다. 정적 멤버는 클래스 메모리에 저장되며 전체 실행에서 한 번만로드되기 때문입니다. 클래스의 모든 객체에 공통입니다. 정적 변수를 final로 선언하면 모든 객체가 최종 값을 변경할 수 없습니다. 따라서 final 및 static으로 선언 된 변수를 상수라고도합니다. 인터페이스의 모든 필드는 기본적으로 최종적이고 정적이므로 상수라고합니다.

여기에 이미지 설명을 입력하십시오

사진 자료 : 최종 정적