这段代码的结果是什么呢,结果出乎我以前对java的认识
public class TestClass {
static void sayHello(P p){
System.out.println("P");
}
static void sayHello(A p){
System.out.println("A");
}
static void sayHello(B p){
System.out.println("B");
}
public static void main(String [] args){
P a = new A();
P b = new B();
sayHello(a);
sayHello(b);
}
//父类
abstract static class P{
}
//子类A
static class A extends P{
}
//子类B
static class B extends P{
}
}
打印结果
P
P
为什么是这样的结果呢,以我的之前的认识 a 和 b 已经是 A 和 B的对象了 应该打印 A 和 B 才是
看一了下编译之后的代码 才明白
这行代码 在常量池定义的方法名称
执行到这段的时候 直接引用的是 常量池的 sayHello(P)的方法 所以上面两个sayHello执行的结果是相同的
下面看更改后的代码 这样执行的结果就会不一样
这是编译之后的class的内容
Classfile /E:/ali/demo/jvmxuexi/bin/com/haojiangbo/demo/TestClass.class
Last modified 2018-8-2; size 1255 bytes
MD5 checksum 0daedcc0bab3cec5d669373374ac3271
Compiled from "TestClass.java"
public class com.haojiangbo.demo.TestClass
SourceFile: "TestClass.java"
InnerClasses:
static #34= #42 of #1; //A=class com/haojiangbo/demo/TestClass$A of class
com/haojiangbo/demo/TestClass
static #38= #45 of #1; //B=class com/haojiangbo/demo/TestClass$B of class
com/haojiangbo/demo/TestClass
static abstract #23= #57 of #1; //P=class com/haojiangbo/demo/TestClass$P
of class com/haojiangbo/demo/TestClass
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // com/haojiangbo/demo/TestClass
#2 = Utf8 com/haojiangbo/demo/TestClass
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/haojiangbo/demo/TestClass;
#14 = Utf8 sayHello
#15 = Utf8 (Lcom/haojiangbo/demo/TestClass$P;)V
#16 = Fieldref #17.#19 // java/lang/System.out:Ljava/io/Prin
tStream;
#17 = Class #18 // java/lang/System
#18 = Utf8 java/lang/System
#19 = NameAndType #20:#21 // out:Ljava/io/PrintStream;
#20 = Utf8 out
#21 = Utf8 Ljava/io/PrintStream;
#22 = String #23 // P
#23 = Utf8 P
#24 = Methodref #25.#27 // java/io/PrintStream.println:(Ljava
/lang/String;)V
#25 = Class #26 // java/io/PrintStream
#26 = Utf8 java/io/PrintStream
#27 = NameAndType #28:#29 // println:(Ljava/lang/String;)V
#28 = Utf8 println
#29 = Utf8 (Ljava/lang/String;)V
#30 = Utf8 p
#31 = Utf8 Lcom/haojiangbo/demo/TestClass$P;
#32 = Utf8 (Lcom/haojiangbo/demo/TestClass$A;)V
#33 = String #34 // A
#34 = Utf8 A
#35 = Utf8 Lcom/haojiangbo/demo/TestClass$A;
#36 = Utf8 (Lcom/haojiangbo/demo/TestClass$B;)V
#37 = String #38 // B
#38 = Utf8 B
#39 = Utf8 Lcom/haojiangbo/demo/TestClass$B;
#40 = Utf8 main
#41 = Utf8 ([Ljava/lang/String;)V
#42 = Class #43 // com/haojiangbo/demo/TestClass$A
#43 = Utf8 com/haojiangbo/demo/TestClass$A
#44 = Methodref #42.#9 // com/haojiangbo/demo/TestClass$A."<
init>":()V
#45 = Class #46 // com/haojiangbo/demo/TestClass$B
#46 = Utf8 com/haojiangbo/demo/TestClass$B
#47 = Methodref #45.#9 // com/haojiangbo/demo/TestClass$B."<
init>":()V
#48 = Methodref #1.#49 // com/haojiangbo/demo/TestClass.sayH
ello:(Lcom/haojiangbo/demo/TestClass$P;)V
#49 = NameAndType #14:#15 // sayHello:(Lcom/haojiangbo/demo/Tes
tClass$P;)V
#50 = Utf8 args
#51 = Utf8 [Ljava/lang/String;
#52 = Utf8 a
#53 = Utf8 b
#54 = Utf8 SourceFile
#55 = Utf8 TestClass.java
#56 = Utf8 InnerClasses
#57 = Class #58 // com/haojiangbo/demo/TestClass$P
#58 = Utf8 com/haojiangbo/demo/TestClass$P
{
public com.haojiangbo.demo.TestClass();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>
":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/haojiangbo/demo/TestClass;
static void sayHello(com.haojiangbo.demo.TestClass$P);
flags: ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljav
a/io/PrintStream;
3: ldc #22 // String P
5: invokevirtual #24 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 5: 0
line 6: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 p Lcom/haojiangbo/demo/TestClass$P;
static void sayHello(com.haojiangbo.demo.TestClass$A);
flags: ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljav
a/io/PrintStream;
3: ldc #33 // String A
5: invokevirtual #24 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 8: 0
line 9: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 p Lcom/haojiangbo/demo/TestClass$A;
static void sayHello(com.haojiangbo.demo.TestClass$B);
flags: ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljav
a/io/PrintStream;
3: ldc #37 // String B
5: invokevirtual #24 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 11: 0
line 12: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 p Lcom/haojiangbo/demo/TestClass$B;
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: new #42 // class com/haojiangbo/demo/TestC
lass$A
3: dup
4: invokespecial #44 // Method com/haojiangbo/demo/Test
Class$A."<init>":()V
7: astore_1
8: new #45 // class com/haojiangbo/demo/TestC
lass$B
11: dup
12: invokespecial #47 // Method com/haojiangbo/demo/Test
Class$B."<init>":()V
15: astore_2
16: aload_1
17: invokestatic #48 // Method sayHello:(Lcom/haojiangb
o/demo/TestClass$P;)V
20: aload_2
21: invokestatic #48 // Method sayHello:(Lcom/haojiangb
o/demo/TestClass$P;)V
24: return
LineNumberTable:
line 14: 0
line 15: 8
line 16: 16
line 17: 20
line 18: 24
LocalVariableTable:
Start Length Slot Name Signature
0 25 0 args [Ljava/lang/String;
8 17 1 a Lcom/haojiangbo/demo/TestClass$P;
16 9 2 b Lcom/haojiangbo/demo/TestClass$P;
}