public class Demo{
public void out(int i){
}
public void out(long l){
}
public static void main(String[] args){
}
}
/*
在转为class文件的时候,会转为字节码,根据字节码可以看出方法的描述符。
重载:
Java中方法的重载在编译期就已经产生了方法的描述符,在执行的时候根据方法的描述符和传入的参数
选择方法执行。这样的形式成为编译期的多态。
为什么Java中重载是以方法名和方法参数来作为方法的描述符的?
回答:因为,在方法执行中,我们有时候只关心方法的执行过程而不关心方法的返回值,所以我们用方法名和方法的返回值作为
方法的描述符。
直白描述:返回值并不能确定和影响你的方法体执行的操作。
多态: 一个对象多种形态。 向下转型必须拥有向上转型之后才可以向下转型。 不可以直接向下转型。
*/
/*
Classfile /C:/Users/Administrator/Desktop/Test.class
Last modified 2020-2-25; size 470 bytes
MD5 checksum 64ab131b71c976b6a84ef554878ee62a
Compiled from "Test.java"
public class Test extends A
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #8.#18 // A."<init>":()V
#2 = Fieldref #19.#20 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #21 // i am Test
#4 = Methodref #22.#23 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #24 // Test
#6 = Methodref #5.#18 // Test."<init>":()V
#7 = Methodref #8.#25 // A.out:()V
#8 = Class #26 // A
#9 = Utf8 <init>
#10 = Utf8 ()V
#11 = Utf8 Code
#12 = Utf8 LineNumberTable
#13 = Utf8 out
#14 = Utf8 main
#15 = Utf8 ([Ljava/lang/String;)V
#16 = Utf8 SourceFile
#17 = Utf8 Test.java
#18 = NameAndType #9:#10 // "<init>":()V
#19 = Class #27 // java/lang/System
#20 = NameAndType #13:#28 // out:Ljava/io/PrintStream;
#21 = Utf8 i am Test
#22 = Class #29 // java/io/PrintStream
#23 = NameAndType #30:#31 // println:(Ljava/lang/String;)V
#24 = Utf8 Test
#25 = NameAndType #13:#10 // out:()V
#26 = Utf8 A
#27 = Utf8 java/lang/System
#28 = Utf8 Ljava/io/PrintStream;
#29 = Utf8 java/io/PrintStream
#30 = Utf8 println
#31 = Utf8 (Ljava/lang/String;)V
{
public Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method A."<init>":()V
4: return
LineNumberTable:
line 8: 0
public void out();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String i am Test
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 10: 0
line 11: 8
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #5 // class Test
3: dup
4: invokespecial #6 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #7 // Method A.out:()V
12: return
LineNumberTable:
line 13: 0
line 14: 8
line 15: 12
}
SourceFile: "Test.java"
C:\Users\Administrator\Desktop>javac Test.java
C:\Users\Administrator\Desktop>java Test
123
C:\Users\Administrator\Desktop>javap -verbose Test
Classfile /C:/Users/Administrator/Desktop/Test.class
Last modified 2020-2-25; size 405 bytes
MD5 checksum b566d315b34bb54f3ca0ed08d60c8db2
Compiled from "Test.java"
public class Test
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#15 // java/lang/Object."<init>":()V
#2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #18 // 123
#4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #21 // Test
#6 = Class #22 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 SourceFile
#14 = Utf8 Test.java
#15 = NameAndType #7:#8 // "<init>":()V
#16 = Class #23 // java/lang/System
#17 = NameAndType #24:#25 // out:Ljava/io/PrintStream;
#18 = Utf8 123
#19 = Class #26 // java/io/PrintStream
#20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V
#21 = Utf8 Test
#22 = Utf8 java/lang/Object
#23 = Utf8 java/lang/System
#24 = Utf8 out
#25 = Utf8 Ljava/io/PrintStream;
#26 = Utf8 java/io/PrintStream
#27 = Utf8 println
#28 = Utf8 (Ljava/lang/String;)V
{
public Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String 123
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 4: 0
line 5: 8
}
SourceFile: "Test.java"
以上就是字节码:
可以看出的有:
1、所有字面量都是存在utf8的常量表中。
2、用到这些字面量的时候会使用指针去指向地址拼接。
3、// Field java/lang/System.out:Ljava/io/PrintStream; 是静态方法。
4、3: ldc #3 // String 123 应该是取值的意思,取常量池三号位的String表中的
指向#18号位的Utf8常量表中的字面量 123;
5、之后调用方法 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 打印出 123;
6、返回
具体细节,俺也不知道,只是知道一个大概- -,继续做笔记。。
*/