"정적 맥락에서 비정적 방법을 참조할 수 없다"는 이면의 이유는 무엇인가?
아주 흔한 초보자 실수는 당신이 클래스의 예를 들지 않고 "정적으로" 클래스 속성을 사용하려고 할 때 발생한다.이렇게 하면 다음과 같은 오류 메시지가 남는다.
비 정적 메서드를 정적으로 만들거나 해당 클래스의 인스턴스를 만들어 속성을 사용할 수 있다.
이런 배경에는 어떤 이유가 있을까?그 해결책에는 관심이 없고, 그 이유는 더더욱 아니다.
private java.util.List<String> someMethod(){
/* Some Code */
return someList;
}
public static void main(String[] strArgs){
// The following statement causes the error.
java.util.List<String> someList = someMethod();
}
존재하지 않는 것을 부를 수는 없다.개체를 만들지 않았기 때문에 정전기 방지 방법은 아직 존재하지 않는다.(정의에 의한) 정적 방법은 항상 존재한다.
호출하려는 방법은 인스턴스 수준 방법이며, 인스턴스가 없는 경우
static
메소드는 클래스에 속하며, 비 클래스에 속함static
방법은 클래스의 인스턴스에 속한다.
객체 지향 프로그래밍의 본질은 그것이 작동하는 데이터와 함께 논리를 캡슐화하는 것이다.
인스턴스 메서드는 논리, 인스턴스 필드는 데이터다.함께, 그들은 물체를 형성한다.
public class Foo
{
private String foo;
public Foo(String foo){ this.foo = foo; }
public getFoo(){ return this.foo; }
public static void main(String[] args){
System.out.println( getFoo() );
}
}
위의 프로그램을 실행한 결과 어떤 결과가 나올 수 있는가?
객체 없이는 인스턴스 데이터는 존재하지 않으며, 인스턴스 메서드가 클래스 정의의 일부로 존재하지만, 이들을 위해 데이터를 제공할 객체 인스턴스가 필요하다.
이론적으로 어떤 인스턴스(instance) 데이터에 접근하지 않는 인스턴스(instance) 방법은 정적 맥락에서 작동할 수 있지만, 그것이 인스턴스(instance) 방식이 될 이유는 없다.그것을 금지하기 위해 별도의 규칙을 마련하기보다는 어쨌든 그것을 허용하는 것이 언어 디자인 결정이다.
나는 사람들이 "정적"이라는 개념에 너무 일찍 노출되어서는 안 된다고 생각했어.
정적인 방법은 아마도 표준보다는 예외일 것이다.특히 OOP를 배우고자 한다면, 어쨌든 일찍부터. (규칙의 예외로 시작하는 이유는?)그것은 Java의 매우 역학적으로, 당신이 배워야 할 "첫" 것은 공공의 정적인 공허함이다. (아무튼 실제 Java 애플리케이션은 그들만의 주요한 방법을 가지고 있다.)
나는 Java 언어의 규칙에 의해 Java 컴파일러가 명시적인 인스턴스 없이 인스턴스 메서드나 인스턴스 필드에 접속하고 있다는 것을 알아차렸을 때, Java 컴파일러가 "이것"과 동등한 것을 삽입한다는 것을 지적할 필요가 있다고 생각한다.물론 정적인 방법으로는 할 수 없듯이 '이' 변수가 있는 인스턴스(instance) 방식 내에서만 이것을 할 수 있다는 것을 컴파일러는 알고 있다.
즉, 인스턴스(instance) 방법을 사용하는 경우 다음이 동등하다는 것을 의미한다.
instanceMethod();
this.instanceMethod();
또한 다음과 같다.
... = instanceField;
... = this.instanceField;
컴파일러는 특정 인스턴스를 제공하지 않을 때 효과적으로 "this"를 삽입하고 있다.
컴파일러에 의한 이 (pun 의도된) "매직 도움말"의 비트는 초보자를 혼동시킬 수 있다. 즉, 실제로는 다른 유형과 기본적인 메커니즘의 호출인 반면 인스턴스 호출과 정적 호출은 때때로 같은 구문을 갖는 것처럼 보인다는 것을 의미한다.
인스턴스 메서드 콜은 다형성을 지원하는 가상 메서드의 행동 때문에 때때로 메서드를 호출하거나 디스패치를 부르기도 한다. 발송 동작은 사용자가 사용할 명시적 객체 인스턴스를 작성했는지 컴파일러가 "이것"을 삽입했는지에 관계없이 발생한다.
정적 메서드 호출 메커니즘은 비 OOP 언어의 함수 호출과 같이 더 단순하다.
개인적으로, 나는 오류 메시지가 오해의 소지가 있다고 생각하는데, 그것은 "명시적인 객체 인스턴스를 지정하지 않고서는 정적인 맥락에서 비정적 방법을 참조할 수 없다"고 읽을 수 있다.
컴파일러가 불평하는 것은 단순히 인스턴스(instance) 방식 내에 표준 "이것"을 삽입할 수 없다는 것이다. 왜냐하면 이 코드는 정적 방법 안에 있기 때문이다. 그러나, 저자는 단지 이 호출에 대한 관심 인스턴스(즉, 매개변수로 제공되거나 생성된 인스턴스)를 제공하는 것을 잊어버렸을 수도 있다.이 정적인 방법으로
간단히 말해, 정적 방법 내에서 인스턴스 메서드를 호출할 수 있는 가장 확실한 방법은 호출에 대한 명시적 인스턴스 개체를 가지고 지정하기만 하면 된다.
지금까지의 답변은 그 이유를 설명하지만, 여기에 여러분이 고려해야 할 다른 것이 있다.
메서드 콜을 생성자에게 추가하여 즉각적인 클래스에서 메서드를 호출할 수 있다.
Object instance = new Constuctor().methodCall();
또는
primitive name = new Constuctor().methodCall();
이는 단일 범위 내에서 한 번만 인스턴스화할 수 있는 클래스의 방법을 사용하고자 하는 경우에만 유용하다.단일 범위 내의 인스턴스 가능한 클래스에서 여러 메서드를 호출하는 경우 반드시 참조 가능한 인스턴스를 만드십시오.
정적 컨텍스트에서 인스턴스(instance) 방법에 액세스하려고 하면 컴파일러는 어떤 인스턴스(instance) 방법(어떤 객체에 대한 변수)을 참조하는지 추측할 방법이 없다.그러나 객체 참조를 사용하여 언제든지 액세스할 수 있다.
정적 방법은 작업을 개체 유형과 연관시키는 반면, 비 정적 방법은 해당 개체 유형의 인스턴스와 관련시킨다.전형적으로 그것은 인스턴스와 관련된 일을 하는 방법이다.
Ex:
클래스 카는 세차 방법이 있을 수 있는데, 이것은 특정한 세차를 나타내는 반면, 정적 방법은 타입 카에 적용된다.
방법이 정적이 아닌 경우, 해당 방법이 클래스의 인스턴스 수준 데이터(비정적 필드)에 대한 액세스를 필요로 하는 컴파일러를 "정적"으로 "정적"클래스의 인스턴스를 만들지 않으면 이 데이터를 사용할 수 없다.그래서 당신이 정적 메서드에서 메서드를 호출하려고 하면 컴파일러는 오류를 발생시킨다.실제로 메소드가 클래스의 비정적 구성원을 참조하지 않는 경우 메소드를 정적으로 만드십시오.
예를 들어 Refarper에서 클래스의 정적 멤버를 참조하지 않는 정전기 방지 방법을 만드는 것만으로도 "이 방법은 정전기화될 수 있다"는 경고 메시지가 생성된다.
컴파일러는 실제로 비정적 방법에 인수를 추가한다.그것은 a를 덧붙인다.this pointer/reference. This is also the reason why a static method can not use this
왜냐하면 물체가 없기 때문이다.
그래서 당신은 아주 핵심적인 이유를 묻는 겁니까?
자바에서 개발 중이므로 컴파일러는 자바 가상 머신이 해석할 수 있는 개체 코드를 생성한다.어쨌든 JVM은 기계 언어로 실행되는 이진 프로그램이다(아마도 당신의 운영 체제와 하드웨어에 특정한 JVM 버전은 당신의 프로세서에서 실행할 수 있는 기계 코드를 얻기 위해 C와 같은 다른 프로그래밍 언어에 의해 이전에 컴파일되었을 것이다).마지막에 모든 코드는 기계 코드로 변환된다.따라서 객체(클래스의 인스턴스)를 만드는 것은 데이터를 읽고 쓸 수 있는 데이터 저장 공간을 확보하기 위해 메모리 공간(운영 체제의 CPU 스케줄러가 프로그램을 큐의 맨 위에 놓을 때 프로세서가 등록할 메모리 레지스터)을 예약하는 것과 같다.클래스의 인스턴스가 없는 경우(정적인 컨텍스트에서 발생), 데이터를 읽거나 쓸 수 있는 메모리 공간이 없는 경우사실, 다른 사람들이 말했듯이, 그 데이터는 존재하지 않는다. 왜냐하면 처음부터 당신이 쓴 적이 없었기 때문이다. 왜냐하면 당신은 그것을 저장할 메모리 공간을 예약하지 않았기 때문이다.
내 영어실력은 정말 미안해!난 라틴계야!
이러한 배경의 간단한 이유는 상위 클래스의 정적 데이터 구성원은 (비정적) 데이터 구성원에 액세스할 수 있지만, 예를 들어, (비정적) 데이터 구성원이나 방법은 참조가 필요하며, 따라서 개체를 통해서만 호출될 수 있기 때문이다.
비정적 방법은 물체에 의존한다.객체가 생성되면 프로그램에 의해 인식된다.
정적 방법은 물체가 생성되기 전에도 호출할 수 있다.정적 방법은 함께 작업할 실제 객체에 종속되지 않는 비교 또는 연산을 수행하는 데 매우 유용하다.
'IT이야기' 카테고리의 다른 글
fflush(stdin) 사용 (0) | 2022.04.28 |
---|---|
"구조 해킹"은 기술적으로 정의되지 않은 행동인가? (0) | 2022.04.28 |
@input 이벤트 실행 메서드 전에 값 프로펠러를 확인하시겠습니까?VeValidate/Vue (0) | 2022.04.28 |
vue-resource http 인터셉터 내부에서 사용자를 리디렉션하는 방법 (0) | 2022.04.28 |
vue js를 사용하여 클릭한 요소의 경고 ID를 선택하십시오. (0) | 2022.04.28 |