Java 정적 귀속과 동적 귀속 깊이 분석
최근에 자바의 지식을 배웠는데 자바의 정적 귀속과 동적 귀속에 대한 학습이 매우 모호하다. 그리고 바이두에서 그에 상응하는 지식을 총괄하고 정리하여 이 부분의 지식을 파악하는 데 도움을 주었다.
프로그램 바인딩 개념:
귀속은 하나의 방법의 호출이 방법이 있는 클래스(방법 주체)와 연결되는 것을 가리킨다.자바에 대해 말하자면 귀속은 정적 귀속과 동적 귀속으로 나뉜다.또는 전기 귀속과 후기 귀속이라고 한다.
정적 바인딩:
프로그램이 실행되기 전에 방법은 이미 귀속되었다. (즉, 컴파일하는 과정에서 이 방법이 도대체 어떤 종류의 방법인지 이미 알고 있다는 것이다.) 이때 컴파일러나 다른 연결 프로그램이 실현된다.예: C.
자바에 대한 간단한 프로그램 컴파일러의 귀속;여기서 특히 한 가지 설명하자면,java 중의 방법은final,static,private와 구조 방법만이 전기 귀속
동적 바인딩:
후기 귀속: 실행할 때 구체적인 대상의 유형에 따라 귀속합니다.
만약에 한 언어가 후기 귀속을 실현하는 동시에 반드시 메커니즘을 제공해야 한다. 운행 기간에 대상의 유형을 판단하고 적당한 방법을 호출할 수 있다.즉, 컴파일러는 지금도 대상의 유형을 모르지만 방법 호출 메커니즘은 스스로 조사하고 정확한 방법 주체를 찾을 수 있다.서로 다른 언어는 후기 귀속의 실현 방법에 대해 차이가 있다.그러나 우리는 적어도 이렇게 생각할 수 있다. 그들은 모두 대상에 특정한 유형의 정보를 삽입해야 한다.
동적 바인딩 프로세스:
프라이빗한 방법에 대해 우선 하나는 상속될 수 없다. 상속될 수 없으면 하위 클래스의 대상을 통해 호출할 수 없고 이 클래스 자체의 대상을 통해서만 호출할 수 있다.따라서 프라이빗 방법과 이 방법을 정의하는 클래스가 한데 묶여 있다고 할 수 있다.
final 방법은 계승될 수 있지만 다시 쓸 수 없습니다. 하위 클래스 대상은 호출할 수 있지만 호출된 것은 모두 상위 클래스에서 정의한 그final 방법입니다. (이로써final 형식으로 설명하는 것을 알 수 있습니다. 첫째, 방법이 덮어쓰는 것을 방지하기 위해서, 둘째, 자바의 동적 귀속을 효과적으로 닫기 위해서입니다.)
구조 방법도 계승될 수 없다. (인터넷에서도 자류가 무조건 부류의 무파라미터 구조 함수를 자신의 구조 함수로 계승한다고 하지만 개인적으로는 이 표현이 적절하지 않다고 생각한다. 왜냐하면 우리는 자류가 슈퍼()를 통해 부류의 무참구조 방법을 호출하여 부류에 대한 초기화를 완성하는 것을 알고 있기 때문이다. 우리는 부류에서 계승된 방법을 사용하면 이렇게 하지 않아도 된다.따라서 자류가 부류의 구조 방법을 계승했다고 해서는 안 된다. 따라서 이 구조 방법이 도대체 어떤 종류에 속하는지 번역할 때도 알 수 있다.
static 방법에 대해 구체적인 원리는 나도 잘 모르겠다.그러나 인터넷의 자료와 내가 한 실험에 의하면 static 방법은 이불류를 계승할 수 있지만 이불류를 다시 쓸 수는 없지만 이불류를 숨길 수 있다는 결론을 얻을 수 있다.(여기서 부모 클래스에 static 방법이 있다면, 하위 클래스에 대응하는 방법이 없다면, 하위 클래스 대상이 이 방법을 호출할 때 부모 클래스의 방법을 사용한다는 뜻이다. 하위 클래스에 같은 방법이 정의되어 있다면, 하위 클래스에 정의된 방법이 호출된다. 유일한 차이점은 하위 클래스 대상이 부모 클래스로 전환될 때, 하위 클래스에 이 정적 방법이 있든 없든 그 대상은상위 클래스의 정적 방법이 사용됩니다.그래서 정적 방법은 숨겨져도 덮어쓸 수 없다고 합니다.이것은 하위 클래스가 부모 클래스의 구성원 변수를 숨기는 것과 같다.숨김과 덮어쓰기의 차이점은 하위 클래스가 상위 클래스로 변환되면 상위 클래스가 덮어쓰는 방법에 접근하지 않고 상위 클래스가 숨겨진 변수와 방법에 접근할 수 있다는 것이다)
위에서 우리는 만약에 하나의 방법이 계승될 수 없거나 계승된 후에 덮어쓸 수 없다면 이 방법은 정적 귀속을 채택할 수 있다는 결론을 얻을 수 있다.
java의 컴파일 및 실행
자바의 컴파일 과정은 자바 원본 파일을 바이트 코드(jvm 실행 가능한 코드, 즉.class 파일)로 컴파일하는 과정이다. 이 과정에서 자바는 메모리와 접촉하지 않는다. 이 과정에서 컴파일러는 문법 분석을 하고 문법이 정확하지 않으면 오류를 보고한다.
Java의 실행 과정은 jvm(java 가상 컴퓨터)가 바이트 파일을 불러오고 실행을 설명하는 것을 가리킨다.이 과정이야말로 진정한 메모리 레이아웃을 만들고 자바 프로그램을 실행하는 것이다.
자바 바이트 코드의 실행은 두 가지 방식이 있다. (1) 실시간 컴파일 방식: 해석기는 먼저 바이트를 기계 코드로 컴파일한 다음에 이 기계 코드를 실행한다.(2) 해석 실행 방식: 해석기는 매번 해석하고 작은 코드를 실행함으로써 자바 바이트 프로그램의 모든 조작을 완성한다.(여기에서 우리는 자바 프로그램이 실행하는 과정에서 사실상 두 번의 전환을 진행했음을 알 수 있다. 먼저 바이트 코드로 전환한 다음에 기계 코드로 전환한다. 이것이 바로 자바가 한 번에 컴파일하여 곳곳에서 실행할 수 있는 이유이다. 서로 다른 플랫폼에 대응하는 자바 가상 기기를 설치하면 같은 바이트 코드를 서로 다른 플랫폼의 기계 코드로 전환시켜 서로 다른 플랫폼에서 실행할 수 있다)
앞에서 말했듯이 자바의 방법에 대해final,static,private와 구조 방법은 전기 귀속을 제외하고 다른 방법은 모두 동적 귀속이다.
동적 귀속의 전형은 상위 클래스와 하위 클래스의 변환 성명 아래에서 발생한다.
예를 들어 Parent p = new Children(),
구체적인 절차는 다음과 같다.
1: 컴파일러는 대상의 성명 형식과 방법 이름을 검사합니다.
만약에 우리가 x.f(args) 방법을 호출하고 x가 C류의 대상으로 성명되었다면 컴파일러는 C류의 모든 이름이 f인 방법과 C류의 초류에서 계승된 f방법을 열거할 것이다.
2: 다음 컴파일러 검사 방법 호출에 제공된 매개 변수 형식입니다.
만약 모든 이름이 f인 방법 중 매개 변수 형식과 호출이 제공하는 매개 변수 형식이 가장 일치한다면, 이 방법을 호출합니다. 이 과정을'재부팅 해석'이라고 합니다.
3: 프로그램이 실행되고 동적 연결 호출 방법을 사용할 때 가상 기기는 x가 가리키는 대상의 실제 유형과 일치하는 방법 버전을 호출해야 한다.
실제 유형이 D(C의 하위 클래스)라고 가정하고 D클래스가 f(String)를 정의하면 이 방법이 호출됩니다. 그렇지 않으면 D의 슈퍼 클래스에서 방법 f(String)를 찾아 순서대로 유추합니다.
JAVA 가상 시스템은 클래스 메서드를 호출할 때 (정적 메서드) 객체 참조의 유형(일반적으로 컴파일할 때 알 수 있음)을 기반으로 호출된 메서드를 선택합니다.반대로 가상 기기가 실례적인 방법을 호출할 때 대상의 실제 유형(운행할 때만 알 수 있음)을 바탕으로 호출된 방법을 선택한다. 이것이 바로 동적 귀속이고 다태적인 것이다.동적 귀속은 실제 업무 문제를 해결하는 데 매우 큰 유연성을 제공하고 매우 아름다운 메커니즘이다.
방법과 달리 자바 클래스의 구성원 변수(실례 변수와 클래스 변수)를 처리할 때 실행 시 귀속을 사용하는 것이 아니라 일반적인 의미의 정적 귀속을 사용한다.따라서 위로 전환하는 상황에서 대상의 방법은 하위 클래스를 찾을 수 있지만 대상의 속성(구성원 변수)은 상위 클래스의 속성(자류가 상위 클래스 구성원 변수에 대한 숨김)이다.
public class Father {
protected String name = " ";
}
public class Son extends Father {
protected String name = " ";
public static void main(String[] args) {
Father sample = new Son();
System.out.println(" :" + sample.name);
}
}
결론, 호출된 구성원은 아버지의 속성이다.이 결과는 하위 클래스의 대상 (부자 클래스의 인용handle) 이 상위 클래스의 구성원 변수로 호출된 것을 나타낸다.따라서 실행할 때 (동적) 귀속이 겨냥한 범주는 대상의 방법일 뿐이라는 것을 명확히 해야 한다.
하위 클래스의 구성원 변수name를 호출하려고 합니다. 어떻게 해야 합니까?가장 간단한 방법은 이 구성원 변수를 방법 getter 형식으로 봉인하는 것이다.
코드는 다음과 같습니다.
public class Father {
protected String name = " ";
public String getName() {
return name;
}
}
public class Son extends Father {
protected String name = " ";
public String getName() {
return name;
}
public static void main(String[] args) {
Father sample = new Son();
System.out.println(" :" + sample.getName());
}
}
결과: 호출된 것은 아들의 속성이다java는 무엇 때문에 속성에 대해 정적 귀속 방법을 취해야 합니까?이것은 정적 연결이 많은 장점이 있기 때문에, 컴파일러에서 프로그램의 오류를 발견할 수 있고, 실행기가 아니라 프로그램의 오류를 발견할 수 있기 때문이다.이렇게 하면 프로그램의 운행 효율을 높일 수 있다!방법에 대해 동적 귀속을 취하는 것은 다태를 실현하기 위한 것이고 다태는java의 큰 특색이다.다태도 대상을 대상으로 하는 관건적인 기술 중 하나이기 때문에 자바는 효율을 대가로 다태를 실현하는 것이 매우 가치가 있다.
주: 상기 내용은 대부분 인터넷에서 왔고 작은 부분은 개인적인 견해이며 절대 권위적인 언론은 아니다.만약 언어 표현이 부적절하거나 표현이 정확하지 않은 곳이 있다면 가르침을 바랍니다.
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.