(에) 자바의 다형성에 구현

자바 구문을 달성 다형성 방법은 두 가지 유형으로 구분된다 : 중장비 2 재기록 또한, 컴파일 시간 다형성 과부하 재기록 알려진 다중 - 상태 동작이다 ..

정확히의 바닥이 방법은 읽고 그것의 다형성을 달성 할 때 다형성을 달성하기 위해, 그래서 "Java 가상 머신에 대한 심층적 인 이해를,"이 책은 (특별한 지침이 책에 대한 참조하지 않는 경우 나중에 책으로 함) 프로세스는 특정 이해를 가지고있다. 다음은 향후 검토를 위해 학습 콘텐츠의 기록이다.

읽기, 갑자기 상하, 주요 기록 과부하 지식, 지식 재 작성의 지점에로 나누어, 조금 더 많은 콘텐츠를 찾을 수 읽기.

과부하

과부하는 방법, 매개 변수의 수, 다른 이름이 같은 메서드 호출 오버로드를 달성하기 위해 매개 변수 순서의 매개 변수 유형에 따라한다하는 것은 정적 할당에 의해 달성된다, 그것은 당신에게 책의 예를 보여주고, 정적 할당 것입니다 코드 :

public class StaticDispatch {
    static abstract class Human {
    }

    static class Man extends Human {
    }

    static class Woman extends Human {
    }

    public void sayHello(Human guy) {
        System.out.println("hello,guy!");
    }

    public void sayHello(Man guy) {
        System.out.println("hello,gentleman!");
    }

    public void sayHello(Woman guy) {
        System.out.println("hello,lady!");
    }

    public static void main(String[] args) {
        Human man = new Man();
        Human woman = new Woman();
        StaticDispatch sr = new StaticDispatch();
        sr.sayHello(man);
        sr.sayHello(woman);
    }
}
//输出:
//hello,guy!
//hello,guy!

IDEA는 컴파일하는 동안 샘플 코드를 호출 할 메서드를 확인했습니다 볼 수있는 회색이라고 불리는되지 않는 방법에서 볼 수 있습니다. 정적 할당을 이해하기 전에, 당신은 실제 정적 유형을 숙지하고이 두 개념을 입력해야합니다.

정적 유형 및 실제 유형

Human man = new Man();

Human변수 (정적 유형), 또는 모양 알려진 유형 (피상 형)의 정적 유형 불리는 Man변수 (실제 타입)의 실제의 형태 함.

이 책은이 말을했다 :

그 자체가 변경되지 변수의 정적 유형을 사용하여, 최종 정적 타입을 컴파일시에 공지되면 정적 유형 및 프로그램 변경에 발생할 수있는 실제 타입이 변화 정지형의 차이가 발생하며 실제 타입 변화의 결과를하는 것은 런타임에 확인하는, 컴파일러 컴파일러는 시간에 모르는 어떤 객체의 실제 타입 예.

이 책의 또 예 :

//实际类型变化
Human man = new Man();
man = new Woman();
// 个人理解:man 的原本的实际类型是 Man,当第 3 行执行时,man 的实际类型就变成了 Woman
//静态类型变化
sr.sayHello((Man) man);
// 个人理解:接着上一步,man 的静态类型是 Human,此时显式转换为 Man,作为 sayHello(Man guy)方法的参数
sr.sayHello((Woman) man);
// 个人理解:前面将 man 的静态类型转换为 Man,但是第 8 行方法中的 man 静态类型还是从 Human 转换成 Woman
// 最终,man 的静态类型还是声明时的 Human

책의 일부를 들어, 다음, 다음 내 개인적인 이해입니다에 대해 조금 이해하는 것입니다 :

  1. 첫째, 정적 유형 및 실제 유형위한 가변의 용어는 변수의 특성을 설명하고, 두 성질은 변화한다;
  2. 실제로 오른쪽 숫자 입력에 할당 된 변수의 타입을 의미 할 때, 정적 유형 선언되는 변수의 형태를 지칭 할 때 변수 할당;
  3. 변화 정지형 두 점에 유의 여기서 사용되는 경우에만 발생한다 : 1) 단지 정적 변수 상수 입력 수단 또는 변수 변경 사용되고, 2) 변수의 최종 정적 유형 변경하거나하지 않을 때 원래 문장의 유형입니다.

StaticDispatch상기 입력 파라미터는 두 통화의 sayHello 메소드를 입력 정적 클래스의 주요 방법은 동일하지만, 배리어의 실제 형태는, 호출의 결과는 동일한 방식이다. 이로부터 우리는이 코드를 실행하기로 결정하기 전에 너무 오버로드 말, 컴파일러가 정적 메서드 호출 유형 매개 변수에 따라 결정, 코드 후 마무리의 정적 유형이 알려진 것을 볼 수 있습니다.

주요 방법 바이트 코드 촬영 :

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=1
      // 0xbb 创建一个对象,并将其引用值压入栈顶
         0: new           #7                  // class jvmlearn/StaticDispatch$Man
         // 0x5c 复制栈顶数值并将复制值压入栈顶
         3: dup
         // 0xb7 调用超类构造方法,实例初始化方法,私有方法
         // 这个指令会用掉当前栈顶的值,所以前面复制了一份
         4: invokespecial #8                  // Method jvmlearn/StaticDispatch$Man."<init>":()V
         // 0x4c 将栈顶引用型数值存入第二个本地变量
         // 可以看下面的局部变量表
         7: astore_1
         8: new           #9                  // class jvmlearn/StaticDispatch$Woman
        11: dup
        12: invokespecial #10                 // Method jvmlearn/StaticDispatch$Woman."<init>":()V
        15: astore_2
        16: new           #11                 // class jvmlearn/StaticDispatch
        19: dup
        20: invokespecial #12                 // Method "<init>":()V
        23: astore_3
        // 0x2d 将第四个引用类型本地变量推送至栈顶
        24: aload_3
        25: aload_1
        // 0xb6 调用实例方法
        // 这里可以直接看到参数是 Human 类型,34 行的代码也一样
        26: invokevirtual #13                 // Method sayHello:(Ljvmlearn/StaticDispatch$Human;)V
        29: aload_3
        30: aload_2
        31: invokevirtual #13                 // Method sayHello:(Ljvmlearn/StaticDispatch$Human;)V
        34: return
      LineNumberTable:// 行号表
        line 30: 0
        line 31: 8
        line 32: 16
        line 33: 24
        line 34: 29
        line 35: 34
      LocalVariableTable:// 局部变量表,存了 main 方法的参数和局部变量,静态方法第一个局部变量不是 this,也没有 this
        Start  Length  Slot  Name   Signature
            0      35     0  args   [Ljava/lang/String;
            8      27     1   man   Ljvmlearn/StaticDispatch$Human;
           16      19     2 woman   Ljvmlearn/StaticDispatch$Human;
           24      11     3    sr   Ljvmlearn/StaticDispatch;

이제 다시 정적 할당의 정의, 모든 송출 동작의 정적 유형의 위치 결정 방법을 실행 버전에 의존하는 전형적인 애플리케이션을 과부하하는 정적의 방법 전달되고, 정적 할당이라고합니다.

특징

정적 할당 방법을 오버로드 결정하는 컴파일러에 의해 컴파일시에 발생하지만이 방법은 유일하게 결정 과부하가 걸리지 않도록 할 수있다. 실제로 컴파일러는 현재 내부 과부하 모든 방법을 알아내는 가장 적합한 하나 있다고합니다. 이 상황에 대한 이유는, 책의 제거를 설명 :

리터럴은 명시 적으로 정적 유형 않고, 그래서 문자를 정의 할 필요는 정적 형식 유추 만 규칙에 가서 언어를 이해할 수있다.

아래는 책에 대해,이 과부하 특성에 대한 샘플 코드는 다음과 같습니다

public class Overload {

    public static void sayHello(Object arg) {
        System.out.println("hello Object");
    }

    public static void sayHello(int arg) {
        System.out.println("hello int");
    }

    public static void sayHello(long arg) {
        System.out.println("hello long");
    }

    public static void sayHello(Character arg) {
        System.out.println("hello Character");
    }

    public static void sayHello(char arg) {
        System.out.println("hello char");
    }

    public static void sayHello(char... arg) {
        System.out.println("hello char ...");
    }

    public static void sayHello(Serializable arg) {
        System.out.println("hello Serializable");
    }

    public static void main(String[] args) {
        sayHello('a');
    }
}

IDEA에 볼 수 있습니다, 호출의 sayHello (문자 ARG) 방법이다. 당신이 방법을 언급하는 경우, 컴파일러는 당신이 다음 메서드 호출을 볼 수 불평하지 않는 것은 sayHello가있다 (INT ARG).

더 테스트 할 수 있습니다, 지속적으로 과부하 방법, 즉 상향식 (bottom-up) 자동 형 변환이, 상향식 (bottom-up) 찾을 규칙 컴파일러 모습을 찾을 수 있습니다, 현재의 메소드 호출을 말한다.

참고

  • "심층 자바 가상 머신의 이해"의 세컨드 에디션 8.3.2 할당 : 1. 정적 할당 P -247

추천

출처www.cnblogs.com/magexi/p/11815902.html