关于java:cs61b-week2Mystery-of-Walrus

58次阅读

共计 2395 个字符,预计需要花费 6 分钟才能阅读完成。

1. 对于赋值的小练习 – 海象之谜:

Walrus a = new Walrus(1000, 8.3);
Walrus b;
b = a;
b.weight = 5;
System.out.println(a);
System.out.println(b);

最终 a 和 b 都会被改成 5,因为对象的赋值是将 a,b 同时指向该内存块,代表同一块内存
与之不同的是

int x = 5;
int y;
y = x;
x = 2;
System.out.println("x is:" + x);
System.out.println("y is:" + y);

将 x 赋值给 y 之后,扭转 x 的值并不会再扭转 y 的值

2.primitive type

java 语言不提供让你晓得变量具体内存地址的办法,与 C 不同,这节俭了咱们对内存的治理,就好比你晓得你的心脏在时刻跳动,但你无奈在某一确切时刻优化其跳动速度,免得犯错误间接将其敞开。
java 申明一个变量后,并不赋初值(primitive type),因而当你想应用你所申明的变量时,必须先赋予其初值。
java 的赋值操作是将 y 的 bit 复制给 x
8 种根本类型:byte, short, int, long, float, double, boolean, char

3. 援用类型

java 的存储,比方 int x,x 在内存中的地址是 200-250, 那么 java 会创立一个盒子存储 x 的第一位数据,也就是 200
当咱们申明一个援用类型的变量时,java 会主动调配一个 64bit 的盒子,无论你贮存任何类型的变量
例如

Walrus someWalrus;
someWalrus = new Walrus(1000, 8.3);

第一行创立一个 someWalrus 盒子,贮存大小 64bit
第二行通过 new 关键字创立实例,大小为 double+int 为 96bit,new 返回其第一个数据的地址, 存在 someWalrus 外面,这也就解释了为何 64bit 大小的盒子却存下了 96bit 大小的实例, 因为它只是存储其地址而非实在的数据值
`Walrus someWalrus;
someWalrus = null;`

如果咱们将 someWalrus 赋值为 null,则 someWalrus 贮存 64 个 0

对于此,如果一个 box notation(someWalrus)值全为 0,则代表 null
如果一个 box notation 的值非 0, 代表其通过箭头指向一个对象实例

综上所述,当咱们执行这段代码时:

Walrus a = new Walrus(1000, 8.3);
Walrus b;
b = a;
b.weight = 5;

创立盒子 a, 贮存 new Walrus(weight1000,size8.3)的地址,创立盒子 b, 暂未赋值,但非 null,b=a,示意将 a 贮存的内存 bit 信息复制给 b,因而 a 与 b 同时指向 Walrus(weight1000,size8.3),所以扭转 b.weight 也会扭转 a, 这就是援用类型和 primitive type 的区别。

4. 参数传递

public static double average(double a,double b)
{return (a+b)/2;
}

在 main 函数外面:

double x=5.5;
double y=10.5
double avg=average(x,y);

在传递参数时同样是遵循 Golden Rule of Equal,即 average 函数创立两个新的盒子 x,y,这两个 x,y 有他本人的作用域,在传递参数时只是将 main 外面的 x,y 复制到 average 外面的 x,y。

5. 一个加深了解的练习:

    public static void main(String[] args) {Walrus walrus = new Walrus(3500, 10.5);
           int x = 9;

           doStuff(walrus, x);
           System.out.println(walrus);
           System.out.println(x);
    }

    public static void doStuff(Walrus W, int x) {
           W.weight = W.weight - 100;
           x = x - 5;
    }

请判断打印出的 x 与 walrus 的值

解决问题的要害是了解 java 在贮存 primitive type 类型变量与 reference type 类型变量的区别,后者的盒子贮存的是 walrus 实例对象的地址,指向 walrus(data 存在其中),而前者则间接贮存其值 data
因而,无论是函数参数传递还是赋值操作,实质上都是将盒子外面存的 bit 复制一份放到新盒子外面去

所以本题中,

public static void doStuff(Walrus W,int x);

首先创立了两个空盒子 W 和 x, 在 main 中执行 doStuff(walrus,x)时,将 main 中的 walrus 和 x 盒子中的值复制一份传递给 doStuff 外面去了,咱们晓得 walrus 外面存储的是 64bit 的地址,而 x 则贮存的是 32bit 的值,因而这样做的后果是:

doStuff 外面的 W 和 main 外面的 walrus 是寄存的同一个地址,因而均指向 Walrus(3500,10.5), 而因为 main 外面的 x 只是贮存的值而非地址,在函数传参时拷贝过来的就是 x 的值,而函数本人也有一个作用域,因而在函数外面对 x 进行减法不影响 main 外面的 x

最终输入是
Walrus(3400,10.5)
x=9 不变
同样是援用类型的还有数组

int [] a;
a=new int[] {1,2,3};

第一行是创立了一个大小为 64bit 的盒子,第二行创立一个大小为 3X32bit 的盒子贮存数据,而后通过 new 关键字返回首地址,= 赋值给第一个盒子,也即是第一个盒子贮存数组的首地址
整个过程是:申明 — 实例化 — 赋值
当初 a 是惟一存储实例对象 {1,2,3} 的地址的盒子,如果咱们此时令
a=new int[] {4,5,6};
那么最开始的 {1,2,3} 的地址就失落了,咱们再也找不到这个对象,将会 Garbage collector 被作为垃圾回收

正文完
 0