정적은 "전역" 또는 "정적"을 의미하며 멤버 변수 및 멤버 메서드를 수정하는 데 사용됩니다. 정적 코드 블록을 형성할 수도 있지만 Java 언어에는 전역 변수라는 개념이 없습니다.
static에 의해 수정된 멤버 변수와 멤버 메서드는 클래스의 개체와 독립적입니다. 즉, 클래스의 특정 인스턴스에 의존하지 않고 클래스의 모든 인스턴스에서 공유됩니다.
이 클래스가 로드되기만 하면 Java Virtual Machine은 기본적으로 클래스 이름을 기준으로 런타임 데이터 영역의 메소드 영역에서 해당 클래스를 찾을 수 있습니다. 따라서 정적 개체는 해당 개체가 생성되기 전에 개체를 참조하지 않고 액세스할 수 있습니다.
public으로 수정된 정적 멤버 변수와 멤버 메서드는 본질적으로 전역 변수이자 전역 메서드입니다. 해당 클래스의 개체가 선언되면 정적 변수의 복사본이 생성되지 않지만 클래스의 모든 인스턴스는 동일한 정적 변수를 공유합니다.
정적 변수 앞에는 비공개 수정이 올 수 있습니다. 즉, 이 변수는 클래스의 정적 코드 블록이나 클래스의 다른 정적 멤버 메서드에서 사용될 수 있습니다(물론 비정적 코드에서도 사용될 수 있음). 멤버 메소드), 하지만 다른 클래스에서는 사용할 수 없습니다. 클래스 이름을 직접 참조하는 것이 중요합니다. 실제로 프라이빗은 액세스 권한 제한을 의미하고 정적은 인스턴스화 없이 사용할 수 있다는 것을 의미하므로 이해하기가 훨씬 쉽습니다. static 앞에 다른 액세스 권한 키워드를 추가하는 효과도 동일합니다.
static으로 수정된 멤버 변수와 멤버 메서드는 일반적으로 정적 변수 및 정적 메서드라고 하며 액세스 구문은 다음과 같습니다.
클래스 이름. 정적 메소드 이름(매개변수 목록...)
클래스 이름.정적 변수 이름
static으로 수정된 코드 블록은 정적 코드 블록을 나타냅니다. JVM(Java Virtual Machine)이 클래스를 로드하면 코드 블록이 실행됩니다(매우 유용합니다. 하하).
1. 정적 변수
클래스 멤버 변수는 정적인지 여부에 따라 두 가지 유형으로 분류할 수 있습니다. 하나는 정적 변수 또는 클래스 변수라고 하는 정적에 의해 수정되는 변수이고, 다른 하나는 인스턴스 변수라고 하는 정적에 의해 수정되지 않는 변수입니다.
둘의 차이점은 다음과 같습니다.
정적 변수의 경우 메모리에 복사본이 하나만 있습니다. JVM은 정적 변수에 대해 한 번만 메모리를 할당합니다. 정적 변수의 메모리 할당은 클래스를 로드하는 과정에서 직접 액세스할 수 있습니다. 클래스 이름(편리함). 물론 객체를 통해 액세스할 수도 있습니다(그러나 권장되지는 않습니다).
인스턴스 변수의 경우 인스턴스가 생성되기 전에 인스턴스 변수에 대해 메모리가 한 번 할당됩니다. 인스턴스 변수는 서로 영향을 주지 않고 메모리에 여러 복사본을 가질 수 있습니다(유연함).
따라서 정적 변수는 일반적으로 다음 두 가지 기능을 구현해야 할 때 사용됩니다.
1).객체간 값을 공유하는 경우
2).변수 접근이 편리한 경우
2. 정적 방법
정적 메서드는 클래스 이름을 통해 직접 호출할 수 있으며, 모든 인스턴스도 호출할 수 있습니다.
따라서 this 및 super 키워드는 정적 메서드에서 사용할 수 없으며, 이들이 속한 클래스의 인스턴스 변수 및 인스턴스 메서드에 직접 접근할 수 없습니다(즉, static이 없는 멤버 변수 및 멤버 메서드만). 자신이 속한 클래스의 멤버 메서드에 액세스할 수 있습니다.
인스턴스 멤버는 특정 개체와 연결되어 있기 때문입니다! 이것은 암기하는 것이 아니라 이해하고 이해하는 것이 필요합니다! ! !
정적 메서드는 모든 인스턴스와 독립적이므로 정적 메서드를 구현해야 하며 추상화할 수 없습니다.
예를 들어, 메서드 호출을 용이하게 하기 위해 Java API의 Math 클래스에 있는 모든 메서드는 정적이며 일반 클래스 내의 정적 메서드도 다른 클래스에서 메서드를 호출할 수 있도록 합니다.
정적 메서드는 클래스 내부의 특수한 유형의 메서드입니다. 해당 메서드는 필요할 때만 정적으로 선언됩니다. 클래스 내부의 메서드는 일반적으로 비정적입니다.
3. 정적 코드 블록
정적 코드 블록은 클래스 멤버와 독립적인 정적 문 블록이라고도 하며, 이러한 정적 코드 블록은 어디에나 배치될 수 있습니다. JVM이 클래스를 로드할 때 실행됩니다. 정적 코드 블록이 여러 개인 경우 JVM은 클래스에 나타나는 순서대로 이를 실행하며 각 코드 블록은 한 번만 실행됩니다. 예를 들어:
공용 클래스 Test5 { 개인 정적 int b; System.out.println(a); System.out println(tb); } static{ Test5.a=4; System.out.println(a) } public static void main(String[] args) { // TODO 메소드 스텁 자동 생성} static{ Test5.a=5; System.out.println(a); } public void f(){ System.out.println("hhahhahah") }
실행 결과:
3
하하하하하
1000
4
5
정적 코드 블록을 사용하여 일부 정적 변수에 값을 할당할 수 있습니다. 마지막으로 다음 예제를 살펴보세요. 모두 정적 기본 메서드가 있으므로 기본 메서드를 실행할 때 인스턴스를 생성하지 않고도 JVM이 직접 호출할 수 있습니다. .
4. static과 final을 함께 사용하면 무엇을 의미하나요?
정적 final은 간단히 "전역 상수"로 이해될 수 있는 멤버 변수 및 멤버 메서드를 수정하는 데 사용됩니다!
변수의 경우, 값이 주어지면 수정할 수 없으며 클래스 이름을 통해 액세스할 수 있음을 의미합니다.
메소드의 경우 이는 재정의할 수 없으며 클래스 이름을 통해 직접 액세스할 수 있음을 의미합니다.
때로는 해당 클래스의 개체와 완전히 독립적으로 사용되도록 클래스 멤버를 정의하려고 합니다. 일반적으로 클래스 멤버는 해당 클래스의 개체를 통해 액세스해야 하지만, 특정 인스턴스를 참조하지 않고 단독으로 사용할 수 있는 멤버를 만드는 것도 가능합니다. 이러한 멤버는 멤버 선언 앞에 static(정적) 키워드를 추가하여 만들 수 있습니다. 멤버가 정적으로 선언되면 개체를 참조하지 않고도 해당 클래스의 개체가 생성되기 전에 액세스할 수 있습니다. 메서드와 변수를 모두 정적으로 선언할 수 있습니다. 정적 멤버의 가장 일반적인 예는 main()입니다. 프로그램이 실행을 시작할 때 main()을 호출해야 하므로 static으로 선언됩니다.
static으로 선언된 변수는 본질적으로 전역 변수입니다. 객체가 선언되면 정적 변수의 복사본이 생성되지 않지만 클래스의 모든 인스턴스 변수는 동일한 정적 변수를 공유합니다. static으로 선언된 메서드에는 다음과 같은 제한 사항이 있습니다.
1). 다른 정적 메서드만 호출할 수 있습니다.
2).정적인 데이터에만 액세스할 수 있습니다.
3). 어떤 식으로든 this 또는 super를 참조할 수 없습니다(키워드 super는 상속과 관련되며 다음 장에서 설명됩니다).
계산을 통해 정적 변수를 초기화해야 하는 경우 정적 블록을 선언하면 클래스가 로드될 때 한 번만 실행됩니다. 다음 예제에서는 정적 메서드, 일부 정적 변수 및 정적 초기화 블록이 포함된 클래스를 보여줍니다.
// 정적 변수, 메서드 및 블록을 보여줍니다. class UseStatic { static int a = 3; static void meth(int x) { System.out.println("x = " + x); println("a = " + a); System.out.println("b = " + b); } static { System.out.println("정적 블록이 초기화되었습니다."); } 공개 정적 void main(String args[]) { meth(42) } }
UseStatic 클래스가 로드되면 모든 정적 문이 실행됩니다. 먼저 a를 3으로 설정한 다음 정적 블록이 실행되고(메시지 인쇄) 마지막으로 b가 a*4 또는 12로 초기화됩니다. 그런 다음 main()이 호출되고, main()이 meth()를 호출하여 값 42를 x에 전달합니다. 세 개의 println() 문은 두 개의 정적 변수 a와 b, 지역 변수 x를 참조합니다.
참고: 정적 메서드에서 인스턴스 변수를 참조하는 것은 불법입니다.
이 프로그램의 출력은 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
정적 블록이 초기화되었습니다.
엑스 = 42
a=3
b = 12
정적 메서드와 변수는 자신이 정의된 클래스 외부의 모든 개체와 독립적으로 사용할 수 있습니다. 이렇게 하면 클래스 이름 뒤에 점 연산자를 추가하기만 하면 됩니다. 예를 들어, 클래스 외부에서 정적 메서드를 호출하려는 경우 다음과 같은 일반 형식을 사용할 수 있습니다.
다음과 같이 코드 코드를 복사합니다.
클래스명.메소드()
여기서 classname은 정적 메소드가 정의된 클래스의 이름입니다. 보시다시피 이 형식은 개체 참조 변수를 통해 비정적 메서드를 호출하는 형식과 유사합니다. 정적 변수는 동일한 형식(클래스 이름 뒤에 점 연산자가 오는 형식)으로 액세스할 수 있습니다. 이것이 Java가 전역 함수 및 전역 변수의 제어된 버전을 구현하는 방법입니다.
아래는 예시입니다. main()에서 정적 메서드 callme()와 정적 변수 b는 해당 클래스 외부에서 액세스됩니다.
클래스 StaticDemo { static int a = 42; static void callme() { System.out.println("a = " + a) } } 클래스 StaticByName { public static void main(String args[]) { StaticDemo.callme(); System.out.println("b = " + StaticDemo.b) } }
이 프로그램의 출력은 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
a=42
b = 99
정적 멤버는 해당 클래스에서 만든 인스턴스에서 액세스할 수 없습니다.
정적 수정이 없는 멤버가 개체 멤버인 경우 각 개체가 소유합니다.
static으로 수정된 멤버는 클래스 멤버입니다. 즉, 클래스에서 직접 호출할 수 있고 모든 개체에 공통됩니다.