구체적으로이 코드를 시도했습니다.
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"클래스의 각각의 인스턴스마다 하나가 아니라, 모든 인스턴스에서 공통적으로 공유되는 "클럭"참조가 하나 있다는 것을 의미합니다. "Hello"클래스.
따라서 코드에서 "새 Hello"를 수행하려면 다음을 수행하십시오. A- 첫 번째 시나리오에서는 (변경 전, "정적"을 사용하지 않고) "새 Hello"가 호출 될 때마다 새 시계를 만들지 만 B- 두 번째 시나리오 (변경 후 "정적"사용)에서 모든 "새 Hello"인스턴스는 처음 생성 된 동일한 "시계"참조를 공유하고 사용합니다.
메인의 바깥 쪽에서 "시계"가 필요하다면, 이것은 잘 작동 할 것입니다 :
package hello;
public class Hello
{
public static void main(String args[])
{
Clock clock=new Clock();
clock.sayTime();
}
}
main()
루틴은 자체 포함되어야합니다. - Jason Smain
왜냐하면 OP가했기 때문입니다. 대신에 다른 곳에서 호출 된 public 메서드이고 Hello 클래스가 두 번 이상 인스턴스화 된 경우 각 Hello 인스턴스에 대해 Clock 인스턴스를 만들 수 있습니다.clock
정적이었다. - Paul Tomblin
그만큼static
키워드 란 무언가 (필드, 메소드 또는 중첩 된 클래스)가유형어떤 특정한 것보다는 오히려예유형의. 예를 들어,Math.sin(...)
어떤 경우도없이Math
계급, 실제로 당신캔트의 인스턴스를 생성한다.Math
수업.
자세한 내용은오라클의 자바 튜토리얼 관련 비트.
쉬
Java 불행히도허락하다인스턴스 멤버 인 것처럼 정적 멤버에 액세스 할 수 있습니다.
// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
그것은 그것을 만든다.보기마치sleep
인스턴스 메소드이지만 실제로는 정적 메소드입니다.항상현재 스레드를 잠자기 상태로 만듭니다. 이 코드를 호출 코드에서 명확하게 만드는 것이 더 좋습니다.
// Clearer
Thread.sleep(5000);
System.out
나에게 유형 이름을 사용하고 싶지 않습니다. - Jon Skeet
그만큼static
Java에서 keyword는 변수 또는 함수가 해당 클래스의 모든 인스턴스간에 공유된다는 것을 의미합니다.유형실제 객체 자체는 아닙니다.
그래서 변수가 있다면 :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";
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의 정적 :
정적은 비 접근 수정 자입니다. static 키워드는 클래스의 인스턴스보다 클래스에 속합니다. 변수 또는 메소드를 클래스에 첨부하는 데 사용할 수 있습니다.
정적 키워드는 다음과 함께 사용할 수 있습니다 :
방법
변하기 쉬운
다른 클래스 내에 상자가 짜 넣어지고있는 클래스
초기화 블록
다음과 함께 사용할 수 없습니다 :
클래스 (중첩되지 않음)
건설자
인터페이스
메서드 로컬 내부 클래스 (차이 및 중첩 된 클래스)
내부 클래스 메서드
인스턴스 변수
지역 변수
예:
다음 예제를 상상해보십시오.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로 선언하면 모든 객체가 최종 값이 될 수 없습니다. 따라서 final 및 static으로 선언 된 변수는 상수라고도합니다. 인터페이스의 모든 필드는 기본적으로 최종 및 정적이기 때문에 상수라고합니다.
그림 자료 :최종 정적
이 논의는 클래스 로더 고려 사항을 지금까지 무시했습니다. 엄밀히 말하면, Java 정적 필드는 주어진 클래스에 대해 클래스의 모든 인스턴스간에 공유됩니다.클래스 로더.
필드는 클래스 또는 클래스의 인스턴스에 할당 될 수 있습니다. 기본적으로 필드는 인스턴스 변수입니다. 사용하여static
필드가 클래스 변수가되므로 하나만 존재합니다.clock
. 한 곳에서 변경을하면 어디서나 볼 수 있습니다. 인스턴스 변수는 서로 독립적으로 변경됩니다.
자바에서는static
키워드는 단순히 다음을 나타내는 것으로 간주 할 수 있습니다.
"특정 인스턴스에 관계없이"
당신이 생각하면static
이런 식으로, 그것이 발생하는 다양한 맥락에서 그것의 사용을 이해하는 것이 더 쉬워진다 :
에이static
필드는 특정 인스턴스가 아닌 클래스에 속한 필드입니다.
에이static
방법은 개념이없는 방법이다.this
; 클래스에 정의되어 있으며 참조가 전달되지 않는 한 해당 클래스의 특정 인스턴스에 대해 알지 못합니다.
에이static
멤버 클래스는 둘러싼 클래스 인스턴스에 대한 개념이나 지식이없는 중첩 클래스입니다 (해당 클래스 인스턴스에 대한 참조가 전달되지 않은 경우).
Static은 시계 멤버를 인스턴스 멤버가 아닌 클래스 멤버로 만듭니다. static 키워드가 없으면 Hello 클래스 (클럭 멤버 변수가 있음)의 인스턴스를 만들어야합니다. 예 :
Hello hello = new Hello();
hello.clock.sayTime();
나는 "도우미"클래스에서 정적 메서드 (가능한 경우에만)에 대한 선호도를 개발했습니다.
호출 클래스는 도우미 클래스의 다른 멤버 (인스턴스) 변수를 생성 할 필요가 없습니다. 헬퍼 클래스의 메서드를 호출하면됩니다. 또한 더 이상 생성자가 필요없고 멤버 (인스턴스) 변수가 필요 없기 때문에 도우미 클래스가 개선되었습니다.
아마 다른 장점이 있습니다.
키워드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();
}
}
"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");
}
}
main()
두 가지 근본적인 제한이있는 정적 메서드입니다.
this()
과super()
정적 컨텍스트에서는 사용할 수 없습니다.
class A {
int a = 40; //non static
public static void main(String args[]) {
System.out.println(a);
}
}
출력 : 컴파일 시간 오류
정적 변수 정적 메서드에서만 액세스 할 수 있으므로 정적 변수를 선언하면 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;
}
}
//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 메소드가 먼저로드됩니다. 그것 때문에static method
. 그런 다음 그것은 객체로 보입니다."a" object
그러나 아직 정의되지 않은 객체. 정적이 아니기 때문에. 그런 다음이 오류와 같이 실행하십시오.