문제

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

package hello;

public class Hello {

    Clock clock = new Clock();

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

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

정적 메서드 메인에서 비 정적 필드에 액세스 할 수 없습니다

그래서 나는 선언을 변경했습니다 clock 이에:

static Clock clock = new Clock();

그리고 그것은 효과가있었습니다. 선언 전에 그 키워드를 넣는 것이 무엇을 의미합니까? 그 대상에 대해 무엇을 할 수 있는지 정확히 무엇을하고/또는 제한 할 것인가?

도움이 되었습니까?

해결책

static 회원은 특정 인스턴스 대신 수업에 속합니다.

그것은 의미합니다 a 하나의 인스턴스 만 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] : 런타임 특성에 따라 클래스 로더 또는 AppDomain 또는 스레드 당 하나 일 수 있지만 포인트 옆에 있습니다.

다른 팁

이는 "hello"클래스의 각 개별 인스턴스 당 하나가 아니라 Hello에 "Clock"인스턴스가 하나만 있다는 것을 의미합니다. "안녕하세요"클래스.

따라서 코드의 어느 곳에서나 "New Hello"를 수행한다면 : A- 첫 번째 시나리오에서 ( "정적"을 사용하지 않고 변경되기 전에) "새로운 Hello"가 호출 될 때마다 새 시계를 만들 것입니다. 그러나 B- 두 번째 시나리오에서 (변경 후, "정적"을 사용한 후) 모든 "New 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 튜토리얼의 관련 비트.


사이드 노트

불행히도 자바 허용 인스턴스 멤버 인 것처럼 정적 멤버에 액세스 할 수 있습니다.

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

그것은 그것을 만듭니다 바라보다 마치 sleep 인스턴스 방법이지만 실제로 정적 방법입니다. 언제나 현재 실을 잠들게합니다. 호출 코드에서 이것을 명확하게하는 것이 더 나은 연습입니다.

// Clearer
Thread.sleep(5000);

그만큼 static Java의 키워드는 변수 또는 함수가 해당 클래스의 모든 인스턴스간에 공유되는 것을 의미합니다. 유형, 실제 대상 자체가 아닙니다.

따라서 변수가있는 경우 : 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
}

이것이 수업 인스턴스를 다른 클래스에 보내지 않고 모든 클래스 멤버에서 값을 공유 할 수있는 방법입니다. 그리고 Whit static 당신은 클래스 인스턴스를 만들 필요가 없습니다.

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

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

Hello.staticValue = "abc";

자바의 정적 :

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

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

방법

변하기 쉬운

수업은 다른 클래스 내에 중첩되었습니다

초기화 블록

다음과 같이 사용할 수 없습니다.

클래스 (중첩되지 않음)

건설자

인터페이스

방법 로컬 내부 클래스 (차이 다음 중첩 클래스)

내부 클래스 방법

인스턴스 변수

로컬 변수

예시:

다음 예를 상상해보십시오 인스턴스 변수는 카운트입니다 생성자에서 증가하는 것 :

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

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

최종 정적 :

다음과 같이 선언 된 글로벌 변수 최종 및 정적 전체 실행에 대해서는 변경되지 않습니다. 정적 멤버는 클래스 메모리에 저장되며 전체 실행에서 한 번만로드됩니다. 그것들은 클래스의 모든 대상에 공통적입니다. 정적 변수를 최종으로 선언하면 객체 중 하나는 최종적으로 값을 변경할 수 없습니다. 따라서 최종 및 정적으로 선언 된 변수를 때로는 상수라고합니다. 인터페이스의 모든 필드는 기본적으로 최종적이고 정적이기 때문에 상수라고합니다.

enter image description here

사진 자원 : 최종 정적

정적은 클래스와 관련된 메소드 또는 변수를 사용하기 위해 클래스의 인스턴스를 만들 필요가 없음을 의미합니다. 예에서는 다음과 같이 호출 할 수 있습니다.

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

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

이 논의는 지금까지 클래스 로더 고려 사항을 무시했습니다. 엄밀히 말하면, Java 정적 필드는 주어진 클래스의 모든 인스턴스간에 공유됩니다. 클래스 로더.

기존 답변에 추가하려면 사진을 사용해 보겠습니다.

모든 저축 계좌에 2%의 이자율이 적용됩니다. 그러므로 그것은입니다 공전.

균형이 있어야합니다 개인, 그렇습니다 ~ 아니다 공전.

enter image description here

필드는 클래스 또는 클래스 인스턴스에 할당 할 수 있습니다. 기본적으로 필드는 인스턴스 변수입니다. 사용하여 static 필드는 클래스 변수가되므로 하나만 있습니다. clock. 한 곳을 변경하면 모든 곳에서 볼 수 있습니다. 인스턴스 가변성은 서로 독립적으로 변경됩니다.

키워드 static 인스턴스가 아닌 클래스 자체에 속하는 필드 또는 메소드를 나타내는 데 사용됩니다. 객체 인 경우 코드 사용 Clock 정적이며 모든 인스턴스입니다 Hello 수업은 이것을 공유합니다 Clock 데이터 구성원 (필드) 공통. 비 정적 인 경우 각각의 개별 인스턴스 Hello 독특한 것을 가질 수 있습니다 Clock 필드.

문제는 a를 추가했다는 것입니다 기본 수업에 대한 방법 Hello 코드를 실행할 수 있도록. 여기서 문제는 기본 메소드는 정적이므로 정적 필드 나 메소드를 참조 할 수 없습니다. 두 가지 방법으로 이것을 해결할 수 있습니다.

  1. 모든 필드와 방법을 만드십시오 Hello 클래스 정적으로 내부에 참조 할 수 있습니다. 기본 방법. 이것은 실제로 좋은 일이 아닙니다 (또는 잘못된 이유가 필드 및/또는 방법 정적을 만드는 잘못된 이유).
  2. 당신의 인스턴스를 만듭니다 Hello 주요 방법 내부의 클래스 및 모든 필드와 메소드는 처음부터 의도 한 방식으로 액세스합니다.

귀하에게 이것은 코드의 다음과 같은 변경을 의미합니다.

package hello;

public class Hello {

    private Clock clock = new Clock();

    public Clock getClock() {
        return clock;
    }

    public static void main(String args[]) {
        Hello hello = new Hello();
        hello.getClock().sayTime();
    }
}

Java에서 static 키워드는 간단히 다음을 나타내는 것으로 간주 할 수 있습니다.

"특정 사례에 대한 관계 나 관계없이"

당신이 생각한다면 static 이런 식으로, 그것이 발생하는 다양한 맥락에서 그 사용을 이해하는 것이 더 쉬워집니다.

  • static 필드는 특정 사례가 아닌 클래스에 속하는 필드입니다.

  • static 방법은 개념이없는 메소드입니다 this; 클래스에 정의되어 있으며 참조가 전달되지 않는 한 해당 클래스의 특정 인스턴스에 대해 알지 못합니다.

  • static 멤버 클래스는 동봉 클래스의 인스턴스에 대한 개념이나 지식이없는 중첩 클래스입니다 (동봉 된 클래스 인스턴스에 대한 언급이 전달되지 않는 한)

static은 클럭 멤버를 인스턴스 멤버 대신 클래스 멤버로 만듭니다. 정적 키워드가 없으면 Hello 클래스의 인스턴스 (클럭 멤버 변수가 있음) -Geg

Hello hello = new Hello();
hello.clock.sayTime();

정적 메소드는 정의 된 클래스의 인스턴스 변수를 사용하지 않습니다. 그 차이에 대한 매우 좋은 설명은에서 찾을 수 있습니다. 이 페이지

"헬퍼"클래스에서 정적 방법 (가능하면 만)에 대한 취향을 개발했습니다.

호출 클래스는 도우미 클래스의 다른 멤버 (인스턴스) 변수를 만들 필요가 없습니다. 당신은 그냥 도우미 클래스의 방법을 호출합니다. 또한 더 이상 생성자가 필요하지 않기 때문에 도우미 클래스가 개선되며 멤버 (인스턴스) 변수가 필요하지 않습니다.

아마도 다른 장점이있을 것입니다.

또한 "이"포인터가없는 정적 멤버를 생각할 수 있습니다. 그들은 모든 사례들 사이에서 공유됩니다.

정적 개념을 이해합니다

public class StaticPractise1 {
    public static void main(String[] args) {
        StaticPractise2 staticPractise2 = new StaticPractise2();
        staticPractise2.printUddhav(); //true
        StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */

        StaticPractise2.printUddhavsStatic1(); //true
        staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static  things and it organizes in its own heap. So, class static methods, object can't reference */

    }
}

이급

public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}

main() 두 가지 기본 제한이있는 정적 방법입니다.

  1. 정적 메소드는 비 정적 데이터 구성원을 사용하거나 직접 비 정적 메소드를 호출 할 수 없습니다.
  2. this() 그리고 super() 정적 컨텍스트에서 사용할 수 없습니다.

    class A {  
        int a = 40; //non static
        public static void main(String args[]) {  
            System.out.println(a);  
        }  
    }
    

출력 : 시간 오류를 컴파일합니다

정적 변수는 정적 메소드에서만 액세스 할 수 있으므로 정적 변수를 선언 할 때 getter와 setter 메소드는 정적 메소드가됩니다.

정적 메소드는 클래스 이름을 사용하여 액세스 할 수있는 클래스 레벨입니다.

다음은 정적 변수 getters and setter에 대한 예입니다.

public class Static 
{

    private static String owner;
    private static int rent;
    private String car;
    public String getCar() {
        return car;
    }
    public void setCar(String car) {
        this.car = car;
    }
    public static int getRent() {
        return rent;
    }
    public static void setRent(int rent) {
        Static.rent = rent;
    }
    public static String getOwner() {
        return owner;
    }

    public static void setOwner(String owner) {
        Static.owner = owner;
    }

}

일부 프로젝트를 실행하면 먼저 정적 인 물건 (변수, 방법, 블록 ..)을로드합니다.

이 프로젝트를 실행하면 먼저 메인 메서드로드를 먼저로드하십시오. 그것의 때문입니다 static method. 그런 다음 객체처럼 보입니다 "a" object . 그러나 객체는 아직 정의되지 않습니다. 비 정적이기 때문에. 그런 다음이 오류처럼 오십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top