'정적'키워드는 클래스에서 무엇을합니까?
구체적으로, 나는이 코드를 시도했다 :
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);
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
}
이렇게하면 클래스 인스턴스 Hello를 다른 클래스로 보내지 않고 모든 클래스 멤버에서 값을 공유 할 수 있습니다. 정적 클래스는 클래스 인스턴스를 만들 필요가 없습니다.
Hello hello = new Hello();
hello.staticValue = "abc";
클래스 이름으로 정적 값이나 메소드를 호출 할 수 있습니다.
Hello.staticValue = "abc";
자바 정적 :
정적은 비 액세스 수정 자입니다. 정적 키워드는 클래스의 인스턴스보다 클래스에 속합니다. 변수 또는 메소드를 클래스에 첨부하는 데 사용할 수 있습니다.
정적 키워드는 다음과 함께 사용할 수 있습니다.
방법
변하기 쉬운
다른 클래스 내에 중첩 된 클래스
초기화 블록
다음과 함께 사용할 수 없습니다 :
클래스 (중첩되지 않음)
건설자
인터페이스
메서드 로컬 내부 클래스 (차이와 중첩 클래스)
내부 클래스 메소드
인스턴스 변수
지역 변수
예:
생성자에서 증가한 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으로 선언 된 변수를 상수라고도합니다. 인터페이스의 모든 필드는 기본적으로 최종적이고 정적이므로 상수라고합니다.
사진 자료 : 최종 정적
정적은 클래스와 연결된 메서드 나 변수를 사용하기 위해 클래스의 인스턴스를 만들 필요가 없음을 의미합니다. 귀하의 예에서 다음을 호출 할 수 있습니다.
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 클래스의 각 인스턴스에 대해 다른 값 / 참조를 가지므로 클래스의 정적 부분에서 액세스 할 수 없습니다.
이 논의에서는 지금까지 클래스 로더 고려 사항을 무시했습니다. 엄밀히 말하면, Java 정적 필드는 주어진 클래스 로더 에 대한 클래스의 모든 인스턴스간에 공유 됩니다.
기존 답변에 추가하려면 그림으로 시도해 보겠습니다.
2 %의 이율이 모든 저축 계좌에 적용됩니다. 따라서 정적 입니다.
잔액은 개별적 이어야 하므로 정적 이 아닙니다 .
필드는 클래스 또는 클래스의 인스턴스에 할당 될 수 있습니다. 기본적으로 필드는 인스턴스 변수입니다. static
필드 를 사용 하면 클래스 변수가되므로 하나만 clock
있습니다. 한 곳에서 변경하면 어디에서나 볼 수 있습니다. 인스턴스 변수는 서로 독립적으로 변경됩니다.
키워드 static
는 인스턴스가 아닌 클래스 자체에 속하는 필드 또는 메소드를 나타내는 데 사용됩니다. 코드를 사용하여 객체 Clock
가 정적 인 경우 Hello
클래스 의 모든 인스턴스는 이 Clock
데이터 멤버 (필드)를 공통으로 공유합니다. 정적이 아닌 경우 각 개별 인스턴스 Hello
는 고유 한 Clock
필드를 가질 수 있습니다 .
문제는 코드를 실행할 수 있도록 클래스에 기본 메소드를 추가 Hello
했다는 것입니다. 여기서 문제는 주요 메소드가 정적이므로 비 정적 필드 또는 그 내부의 메소드를 참조 할 수 없다는 것입니다. 두 가지 방법으로이 문제를 해결할 수 있습니다.
- 기본 메소드
Hello
내에서 참조 될 수 있도록 클래스 의 모든 필드와 메소드를 정적 으로 작성하십시오 . 이것은 실제로 좋은 일이 아닙니다 (또는 잘못된 이유는 필드 및 / 또는 메소드를 정적으로 만듭니다) 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 클래스 (클럭 멤버 변수가있는)의 인스턴스를 만들어야합니다. 예 :
Hello hello = new Hello();
hello.clock.sayTime();
정적 메소드는 정의 된 클래스의 인스턴스 변수를 사용하지 않습니다. 차이점에 대한 아주 좋은 설명은 이 페이지 에서 찾을 수 있습니다
나는 "helper"클래스에서 정적 메소드 (가능한 경우에만)를 좋아하는 것을 개발했다.
호출 클래스는 도우미 클래스의 다른 멤버 (인스턴스) 변수를 만들 필요가 없습니다. 헬퍼 클래스의 메소드를 호출하기 만하면됩니다. 또한 더 이상 생성자가 필요없고 멤버 (인스턴스) 변수가 필요하지 않기 때문에 도우미 클래스가 향상되었습니다.
아마도 다른 장점이있을 것입니다.
정적 멤버에 "this"포인터가없는 것으로 생각할 수도 있습니다. 모든 인스턴스간에 공유됩니다.
정적 개념 이해
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()
두 가지 기본 제한 사항이있는 정적 메소드입니다.
- 정적 메소드는 비 정적 데이터 멤버를 사용하거나 비 정적 메소드를 직접 호출 할 수 없습니다.
this()
그리고super()
정적 컨텍스트에서 사용할 수 없습니다.class A { int a = 40; //non static public static void main(String args[]) { System.out.println(a); } }
출력 : 컴파일 시간 오류
정적 변수 정적 메소드에서만 액세스 할 수 있으므로 정적 변수를 선언하면 해당 getter 및 setter 메소드가 정적 메소드가됩니다.
정적 메소드는 클래스 이름을 사용하여 액세스 할 수있는 클래스 레벨입니다.
다음은 정적 변수 Getter 및 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
. 그러나 객체는 아직 정의되지 않았습니다. 비 정적이기 때문입니다. 그런 다음이 오류가 발생합니다.
참고 URL : https://stackoverflow.com/questions/413898/what-does-the-static-keyword-do-in-a-class
'Programming' 카테고리의 다른 글
LINQ to SQL의 내부 조인 구문은 무엇입니까? (0) | 2020.02.18 |
---|---|
Maven 저장소에서 소스 JAR 가져 오기 (0) | 2020.02.18 |
배열 필드가 비어 있지 않은 MongoDB 레코드 찾기 (0) | 2020.02.18 |
jQuery 또는 getElementById와 같은 DOM 메소드가 요소를 찾지 못하는 이유는 무엇입니까? (0) | 2020.02.17 |
파이썬에서 배열을 선언하는 방법? (0) | 2020.02.17 |