>  기사  >  Java  >  07.Java 기초 - 정적 바인딩과 동적 바인딩

07.Java 기초 - 정적 바인딩과 동적 바인딩

黄舟
黄舟원래의
2017-02-27 10:29:531240검색

기본 개념

바인딩은 메서드 호출을 해당 클래스와 연결하는 것을 의미합니다.

바인딩은 정적 바인딩과 동적 바인딩으로 나눌 수 있습니다.

정적 바인딩과 동적 바인딩을 분석하기 전에 알아야 할 몇 가지 개념:

  • 컴파일 기간: 컴파일 프로세스는 Java 소스를 변환하는 것입니다. 파일을 바이트코드(.class 파일, JVM 실행 코드)로 컴파일하는 과정입니다. 이 과정에서 Java는 메모리를 처리하지 않습니다. 이 과정에서 컴파일러는 구문 분석을 수행합니다. 보고되었습니다.

  • 실행 기간: 실행 프로세스는 JVM(Java Virtual Machine)이 바이트코드 파일을 로드하고 이를 해석하여 실행하는 것을 의미합니다. 메모리 Java 프로그램을 실행합니다.


메소드 호출

Java에서 메소드 호출 과정은 다음과 같습니다.

  • Editor 해당 객체의 선언된 타입과 메소드 이름을 확인합니다. 메서드 오버로드로 인해 호출될 수 있는 모든 후보 메서드를 가져옵니다. 예를 들어, 메소드 1은 print(String str)이고, 메소드 2는 print(int)입니다.

  • 컴파일러는 호출 메서드의 입력 매개변수 유형을 확인합니다. 후보 방법 중에서 일치 방법을 선택합니다. 예를 들어 입력 매개변수가 "hello"인 경우 print(String str)을 선택합니다.

  • 메서드가 private, static, final 또는 생성자인 경우 컴파일러는 호출할 메서드를 결정할 수 있습니다. 이것은 정적 바인딩입니다.

  • 그렇지 않은 경우 런타임(동적) 바인딩을 사용해야 합니다.


정적 바인딩

정적 바인딩, 초기 바인딩 및 컴파일 타임 바인딩이라고도 합니다. 컴파일 타임에 바인딩을 나타냅니다. 즉, 프로그램이 실행되기 전에 메서드가 바인딩되었음을 나타냅니다.

final, static 및 private으로 수정된 메서드, 멤버 변수 및 생성자만 정적으로 바인딩됩니다.

类型 解释
final 被其修饰的方法可以被继承,但不能被重写;子类对象可以调用,但是调用的是父类中定义的那个方法;间接表明将方法声明为 final 可以避免重写,关闭动态绑定。
private 被其修饰地方法隐式地包含了 final 关键字。由于它对外是不可见的,所以不能被继承,重写;只能通过类自身的对象来调用,因此在方法运行之前就可以明确对象。
static 静态方法是依赖于类而依赖于对象的。它可以被子类继承(实质是被子类隐藏),但是不能被子类重写。当子类对象向上转型为父类对象时,不论子类中有没有定义这个静态方法,该对象都会使用父类中的静态方法。因此这里说静态方法可以被隐藏。
成员变量 默认 Java 对属性采用静态绑定,这样在编译期就能发现程序错误,能够提供效率。
构造方法 构造方法不能被继承的,子类继承父类时默认要先调用父类的构造方法(无论显示或隐式)。因此在程序运行之前就可以知道构造方法术语哪个对象。

다음 예를 살펴보세요.

// 父类class Parent{    // 变量
    String name="Parent";    // 静态方法
    static void print(){
        System.out.println("Parent print");
    }    // 私有方法
    private void say(){
        System.out.println("Parent say");
    }    // 终态方法
    final void look(){
        System.out.println("Parent look");
    }
}// 子类class Son extends Parent{
    String name ="Son";    static void print(){
        System.out.println("Son print");
    }    // 编译错误,无法重写父类的 final方法
    final void look(){};
}public class Test{
    public static void main(String[] args) {        // 发生向上转型
        Parent p = new Son();        // 输出 Parent
        System.out.println(p.name);        // 输出 Parent print
        p.print();        // 编译错误,对外不可见
        p.say();
    }
}

동적 바인딩

동적 바인딩은 런타임 바인딩이라고도 하며 런타임 시 특정 개체의 유형에 따라 바인딩하는 것을 의미합니다.

동적 바인딩 프로세스:

  • 가상 머신은 객체의 실제 유형의 메소드 테이블을 추출합니다.

  • 가상 기계 검색 메소드 서명

  • 이 메소드를 호출합니다.

예를 살펴보겠습니다.

class A {    int x = 5;
}

class B extends A {    int x = 6;
}

class Parent {    public A getValue() {
        System.out.print("Parent Method ");        return new A();
    }
}

class Son extends Parent {    public B getValue() {
        System.out.print("Son Method ");        return new B();
    }
}public class Test {
    public static void main(String[] args) {        // 向上转型
        Parent p = new Son();        // 输出结果:Son Method 5
        // 注意:是 5 不是 6 !
        System.out.println(p.getValue().x);
    }
}

다음과 같이 출력 분석을 관찰합니다.

  • p.getValue(), 발생으로 인해 상향 변환이 있으므로 먼저 하위 클래스(Son)에서 메서드를 검색하고, 이때 Son의 메서드를 호출합니다. 이것이 동적 바인딩입니다.

  • p.getValue( ).x. x는 멤버 변수이므로 여기에서 정적 바인딩이 실행되기 전에 해당 개체(Parent에 속함)가 결정됩니다.

아직도 이해가 되지 않는다면 다른 예를 살펴보겠습니다.

class Parent {
    String name = "Parent " + this.getClass().getName();
}

class Son extends Parent {
    String name = "Son" + this.getClass().getName();
}public class Test {
    public static void main(String[] args) {        // 向上转型
        Parent p = new Son();        // 输出:Parent Son
        System.out.println(p.name);
    }
}

다음과 같이 출력 분석을 관찰합니다.

  • p.name : name은 멤버 변수이고 이때 static 바인딩이 발생하므로 Parent의 속성이 호출됩니다.

  • this.getClass( ): getClass는 이때 상향 변환이 발생하므로 기본 프로그램은 이 메소드도 존재하는 하위 클래스부터 검색합니다. 서브클래스. 따라서 서브클래스의 메소드가 호출되며 이때 동적 바인딩이 발생하게 된다.


위 내용은 07.Java Basics - Static Binding & Dynamic Binding의 내용입니다. 자세한 내용은 PHP 중국어를 참고해주세요. 홈페이지(www.php.cn)!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.