目录
[tpc]
Java数据类型
Java变量类型可以分为两种,一种是存储在堆栈中的基本数据类型,一种是存储在堆里的Java对象。
基本数据类型有9种,4种整型,2种浮点型,1种Unicode字符型,1种布尔类型,1种void类型。
void类型用于方法返回值,表示没有返回值。
基本类型 | 大小(字节) | 包装器类型 |
---|---|---|
byte | 1 | Byte |
short | 2 | Short |
int | 4 | Integer |
long | 8 | Long |
float | 4 | Float |
double | 8 | Double |
char | 2 | Character |
boolean | -- | Boolean |
void | -- | Void |
引用
引用是一个经常看到的词,可以理解为一种操纵对象的手段。创建对象的引用并不代表着创建对象。
比如String str
表示创建了一个对象的引用变量,变量str
目前还没有引用任何对象。
str="hello"
,此时变量str
引用"hello"
字符串对象。
父类的变量可以引用子类的对象。接口的变量可以引用实现类的对象。
方法参数
Java中方法参数的传递全部是按值传递,也就是说传递给方法的参数都是一份新的拷贝。
以下是想要交换两个数的方法,但结果是错误的。因为传递给方法的参数是一份新的拷贝,之前的值是没有变化的。
package com.hnzhrh.fundamental; import java.util.*; public class Test{ public static void main(String[] args){ int a=10; int b=5; swap(a,b); } private static void swap(int a,int b){ int temp=a; a=b; b=temp; } }
方法的执行依赖着操作数栈、局部变量表和程序计数器,并且是方法私有的。对上述程序反编译:
javap -v -p Test.class
得到带有附加信息的字节码,-v
选项表示输出带有附加信息,-p
选项表示显示所有类和成员。
截取main方法部分和swap方法部分内容:
40 public static void main(java.lang.String[]); 41 descriptor: ([Ljava/lang/String;)V 42 flags: ACC_PUBLIC, ACC_STATIC 43 Code: 44 stack=2, locals=3, args_size=1 45 0: bipush 10 46 2: istore_1 47 3: iconst_5 48 4: istore_2 49 5: iload_1 50 6: iload_2 51 7: invokestatic #2 // Method swap:(II)V 52 10: return 53 LineNumberTable: 54 line 7: 0 55 line 8: 3 56 line 9: 5 57 line 10: 10 58 59 private static void swap(int, int); 60 descriptor: (II)V 61 flags: ACC_PRIVATE, ACC_STATIC 62 Code: 63 stack=1, locals=3, args_size=2 64 0: iload_0 65 1: istore_2 66 2: iload_1 67 3: istore_0 68 4: iload_2 69 5: istore_1 70 6: return 71 LineNumberTable: 72 line 12: 0 73 line 13: 2 74 line 14: 4 75 line 15: 6
(44行开始)
初始状态:
main方法的参数args存储在局部变量表0号位置中。
bipush 10
10进入操作数栈,istore_1
栈顶元素10出栈并存入局部变量表1号位置。
iconst_5
常数5进入操作数栈,istore_2
栈顶元素5出栈并存入局部变量表2号位置。
iload_1
局部变量表1号位置里的10入栈。
iload_2
局部变量表2号位置里的5入栈。 调用方法swap(10,5)
,该方法有自己的操作数栈、局部变量表和程序计数器。
参数10存储在局部变量表0号位置,参数5存储在局部变量表1号位置。
iload_0
局部变量表0号位置的10元素入栈。
istore_2
操作数栈栈顶元素10出栈并存储到局部变量表2号位置。 iload_1
局部变量表1号位置的5入栈。
istore_0
操作数栈栈顶元素5出栈并存入局部变量表0号位置。 iload_2
局部变量表2号位置的10入栈。
istore_1
栈顶元素10出栈并存储到局部变量表1号位置。 return
方法,方法执行完毕,销毁栈帧,只是把swqp
方法里局部变量表里的参数a跟b互换了,而原本的a和b还原封不动。
需要注意的是,静态方法局部变量表0号位置的元素是方法第一个参数,而非静态方法的局部变量表0号元素是this,即对象本身。
技术上使静态方法不能通过this调用方法。