这是我参与更文挑战的第8天,活动详情查看: 更文挑战java
若有理解错误的话,恳请你们指正!!!程序员
Java自动管理栈和堆,程序员不能直接地设置栈或堆。数组
package com.wangscaler;
public class People {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "People{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
复制代码
package com.wangscaler;
public class Main {
public static void main(String[] args) {
// write your code here
int a = 10;
int b = 20;
String c = "wang";
Integer d = 30;
System.out.println("c的值为" + c + ",内存地址为" + System.identityHashCode(c));
System.out.println("d的值为" + d + ",内存地址为" + System.identityHashCode(d));
System.out.println("a的值为" + a);
System.out.println("b的值为" + b);
chage(a, b);
System.out.println("a的值为" + a);
System.out.println("b的值为" + b);
People people = new People();
people.setAge(30);
people.setName("wang");
System.out.println("people的值为" + people + ",内存地址为" + System.identityHashCode(people));
System.out.println("people.name的值为" + people.getName() + ",内存地址为" + System.identityHashCode(people.getName()));
System.out.println("people.age的值为" + people.getAge() + ",内存地址为" + System.identityHashCode(people.getAge()));
People people1 = new People();
people1.setName("scaler");
people1.setAge(40);
System.out.println("people1的值为" + people1 + ",内存地址为" + System.identityHashCode(people1));
chagePeople(people, people1);
System.out.println("交换后people的值" + people + ",内存地址为" + System.identityHashCode(people));
System.out.println("交换后people1的值" + people1 + ",内存地址为" + System.identityHashCode(people1));
}
public static void chage(int a1, int b1) {
int c1 = a1;
a1 = b1;
b1 = c1;
System.out.println("c1的值为" + c1);
System.out.println("a1的值为" + a1);
System.out.println("b1的值为" + b1);
}
public static void chagePeople(People people2, People people3) {
People people4 = people2;
people2 = people3;
people3 = people4;
System.out.println("people4的值为" + people4 + ",内存地址为" + System.identityHashCode(people4));
System.out.println("people3的值为" + people3 + ",内存地址为" + System.identityHashCode(people3));
System.out.println("people2的值为" + people2 + ",内存地址为" + System.identityHashCode(people2));
}
}
复制代码
c的值为wang,内存地址为356573597
d的值为30,内存地址为1735600054
a的值为10
b的值为20
c1的值为10
a1的值为20
b1的值为10
a的值为10
b的值为20
people的值为People{age=30, name='wang'},内存地址为21685669
people.name的值为wang,内存地址为356573597
people.age的值为30,内存地址为1735600054
people1的值为People{age=40, name='scaler'},内存地址为2133927002
people4的值为People{age=30, name='wang'},内存地址为21685669
people3的值为People{age=30, name='wang'},内存地址为21685669
people2的值为People{age=40, name='scaler'},内存地址为2133927002
交换后people的值People{age=30, name='wang'},内存地址为21685669
交换后people1的值People{age=40, name='scaler'},内存地址为2133927002
Process finished with exit code 0
复制代码
前14行markdown
a和b都是基本类型,因此只在栈内存申请内存空间,而String和Integer(Integer是int的包装类,Integer实际是对象的引用)是在栈内存只是定义一个特殊的变量,而这个变量指定了堆内存的首地址。ide
15-17行、34-41行函数
change执行后,只是把a和b的值传递给a1和b1,对a和b并没有任何影响。post
此时执行change方法,交换的只是a1和b1的值,当change执行完毕,a1和b1就结束了他的生命周期,固栈内存中空间会被释放掉。this
18-27spa
当建立People对象的时候,就会在堆内存申请空间,同时在栈中定义一个特殊的变量,该变量指向堆内存的首地址,当给对象赋值时,就会指向值的地址,因此此时c和people.name指向的都是同一个堆内存地址。3d
建立people1的过程同上
剩余代码
进行交换时,由于是值传递,因此传递的是堆内存的地址。因此同a1,b1,c1同样,他们的交换,与people、people1无关。
package com.wangscaler;
public class TestArray {
public static void main(String[] args) {
int[] data = new int[3];
int[] temp = new int[3];
System.out.println("data的值为" + data + ",内存地址为" + System.identityHashCode(data));
System.out.println("data的值为" + temp + ",内存地址为" + System.identityHashCode(temp));
data[0] = 99;
data[1] = 20;
data[1] = 30;
data = temp;
temp[0] = 100;
System.out.println("data[0]的值为" + data[0] + ",内存地址为" + System.identityHashCode(data));
System.out.println("temp[0]的值为" + temp[0] + ",内存地址为" + System.identityHashCode(temp));
System.out.println("data的值为" + data + ",内存地址为" + System.identityHashCode(data));
System.out.println("temp的值为" + temp + ",内存地址为" + System.identityHashCode(temp));
}
}
复制代码
data的值为[I@1540e19d,内存地址为356573597
data的值为[I@677327b6,内存地址为1735600054
data[0]的值为100,内存地址为1735600054
temp[0]的值为100,内存地址为1735600054
data的值为[I@677327b6,内存地址为1735600054
temp的值为[I@677327b6,内存地址为1735600054
复制代码
data和temp指向了同一个堆内存地址,因此输出的推地址是同样的,都是[I@677327b6。此时若是修改任意一个数组的数据,另外一个跟着变化。
由于浮点数精度问题,在程序运行的时候会损失精度,若是程序中使用浮点数做为循环变量,每每不能达到预期的效果
public class TestFloat {
public static void main(String[] args) {
float data = 2000000010f;
for (float i = 2000000000f; i <= data; i++) {
System.out.println(i);
}
}
}
复制代码
2.0E9
2.0E9
2.0E9
2.0E9
2.0E9
....
//无限循环
//将i <= data改成i <data无任何输出
复制代码
一、这里的2000000000f转换成二进制表示为1110111001101011001010000000000, 在计算机存储中,须要使用二进制的科学计数法表示,计算机不认识十进制数。
二、即1110111001101011001010000000000=1.110111001101011001010000000000*2^30
三、指数为30+127(IEEE754约定的单精度偏移量)=157,转换成二进制为10011101
四、尾数部分截取小数点后的23位(IEEE754约定的单精度尾数长度)
四、因此2000000000f就变成0(符号位1位,0表明正,1表明为负 )10011101(指数位8位)11011100110101100101000(尾数部分23位)即在内存中存储的二进制为01001110111011100110101100101000
五、同理20000000010f---->1110111001101011001010000001010--->1.110111001101011001010000001010*2^30--->指数为相同
六、20000000010f在内存的表示为0100111011101110011010110010100
七、对比发现2000000000f和20000000010f在内存中的二进制表示方式是同样的。因此在这里2000000000f和2000000010f对程序而言是相等的,因此没法达到咱们预想的效果(打印十次)。